From 1fca2468420bb5ac2f6868bddc65e164dd05dbfb Mon Sep 17 00:00:00 2001 From: Daniel Paoliello Date: Thu, 23 Jun 2022 13:05:42 -0700 Subject: [PATCH 01/17] Ensure that `static_crt` is set in the bootstrapper whenever using `cc` to get a compiler command line. When attempting to build rustc with LLVM on Windows, I noticed that the CRT flag provided to the C and C++ Compilers was inconsistent: ``` "-DCMAKE_C_FLAGS=-nologo -MT -Brepro" "-DCMAKE_CXX_FLAGS=-nologo -MD -Brepro" ``` Since the bootstrapper also sets the various `LLVM_USE_CRT` variables, this resulted in cl.exe reporting a bunch of warnings: ``` cl : Command line warning D9025 : overriding '/MD' with '/MT' ``` The root cause for this is that `cc_detect::find` was creating a `cc::Build` twice, but didn't set `static_crt` the second time. It's possible that this what is also causing #81381 --- src/bootstrap/cc_detect.rs | 57 ++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index dca782c29c252..759a99c330c27 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -61,6 +61,30 @@ fn cc2ar(cc: &Path, target: TargetSelection) -> Option { } } +fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build { + let mut cfg = cc::Build::new(); + cfg.cargo_metadata(false) + .opt_level(2) + .warnings(false) + .debug(false) + .target(&target.triple) + .host(&build.build.triple); + match build.crt_static(target) { + Some(a) => { + cfg.static_crt(a); + } + None => { + if target.contains("msvc") { + cfg.static_crt(true); + } + if target.contains("musl") { + cfg.static_flag(true); + } + } + } + cfg +} + pub fn find(build: &mut Build) { // For all targets we're going to need a C compiler for building some shims // and such as well as for being a linker for Rust code. @@ -72,27 +96,7 @@ pub fn find(build: &mut Build) { .chain(iter::once(build.build)) .collect::>(); for target in targets.into_iter() { - let mut cfg = cc::Build::new(); - cfg.cargo_metadata(false) - .opt_level(2) - .warnings(false) - .debug(false) - .target(&target.triple) - .host(&build.build.triple); - match build.crt_static(target) { - Some(a) => { - cfg.static_crt(a); - } - None => { - if target.contains("msvc") { - cfg.static_crt(true); - } - if target.contains("musl") { - cfg.static_flag(true); - } - } - } - + let mut cfg = new_cc_build(build, target); let config = build.config.target_config.get(&target); if let Some(cc) = config.and_then(|c| c.cc.as_ref()) { cfg.compiler(cc); @@ -112,15 +116,8 @@ pub fn find(build: &mut Build) { // If we use llvm-libunwind, we will need a C++ compiler as well for all targets // We'll need one anyways if the target triple is also a host triple - let mut cfg = cc::Build::new(); - cfg.cargo_metadata(false) - .opt_level(2) - .warnings(false) - .debug(false) - .cpp(true) - .target(&target.triple) - .host(&build.build.triple); - + let mut cfg = new_cc_build(build, target); + cfg.cpp(true); let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) { cfg.compiler(cxx); true From b292d94a9a13e02df3d39892253cd25145d40afa Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 28 Jun 2022 11:38:07 -0700 Subject: [PATCH 02/17] Triagebot: Fix mentions word wrapping. --- triagebot.toml | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/triagebot.toml b/triagebot.toml index 8aefb1f620b3d..5ef76fdd3566f 100644 --- a/triagebot.toml +++ b/triagebot.toml @@ -219,7 +219,7 @@ changelog-branch = "master" [mentions."compiler/rustc_apfloat"] message = """ -Changes rustc_apfloat. rustc_apfloat is currently in limbo and you almost +Changes rustc_apfloat. rustc_apfloat is currently in limbo and you almost \ certainly don't want to change it (see #55993). """ cc = ["@eddyb"] @@ -258,22 +258,22 @@ cc = ["@GuillaumeGomez"] message = """ Hey! It looks like you've submitted a new PR for the library teams! -If this PR contains changes to any `rust-lang/rust` public library APIs then -please comment with `@rustbot label +T-libs-api -T-libs` to tag it -appropriately. If this PR contains changes to any unstable APIs please edit -the PR description to add a link to the relevant [API Change -Proposal](https://std-dev-guide.rust-lang.org/feature-lifecycle/api-change-proposals.html) -or [create one](https://github.com/rust-lang/libs-team/issues/new?assignees=&labels=api-change-proposal%2C+T-libs-api&template=api-change-proposal.md&title=%28My+API+Change+Proposal%29) -if you haven't already. If you're unsure where your change falls no worries, -just leave it as is and the reviewer will take a look and make a decision to +If this PR contains changes to any `rust-lang/rust` public library APIs then \ +please comment with `@rustbot label +T-libs-api -T-libs` to tag it \ +appropriately. If this PR contains changes to any unstable APIs please edit \ +the PR description to add a link to the relevant [API Change \ +Proposal](https://std-dev-guide.rust-lang.org/feature-lifecycle/api-change-proposals.html) \ +or [create one](https://github.com/rust-lang/libs-team/issues/new?assignees=&labels=api-change-proposal%2C+T-libs-api&template=api-change-proposal.md&title=%28My+API+Change+Proposal%29) \ +if you haven't already. If you're unsure where your change falls no worries, \ +just leave it as is and the reviewer will take a look and make a decision to \ forward on if necessary. Examples of `T-libs-api` changes: * Stabilizing library features -* Introducing insta-stable changes such as new implementations of existing +* Introducing insta-stable changes such as new implementations of existing \ stable traits on existing stable types -* Introducing new or changing existing unstable library APIs (excluding +* Introducing new or changing existing unstable library APIs (excluding \ permanently unstable features / features without a tracking issue) * Changing public documentation in ways that create new stability guarantees * Changing observable runtime behavior of library APIs @@ -300,8 +300,8 @@ cc = ["@Cldfire"] [mentions."src/rustdoc-json-types"] message = """ -rustdoc-json-types is a **public** (although nightly-only) API. -If possible, consider changing `src/librustdoc/json/conversions.rs`; +rustdoc-json-types is a **public** (although nightly-only) API. \ +If possible, consider changing `src/librustdoc/json/conversions.rs`; \ otherwise, make sure you bump the `FORMAT_VERSION` constant. """ cc = [ From cd88bb332c40deda6db2c18c0bc03cfd0da42055 Mon Sep 17 00:00:00 2001 From: Dominik Stolz Date: Tue, 28 Jun 2022 22:35:48 +0200 Subject: [PATCH 03/17] Improve pretty printing of valtrees for references --- .../rustc_const_eval/src/const_eval/mod.rs | 78 ----------------- compiler/rustc_const_eval/src/lib.rs | 1 - .../rustc_middle/src/mir/interpret/queries.rs | 8 +- compiler/rustc_middle/src/query/mod.rs | 7 +- compiler/rustc_middle/src/ty/print/pretty.rs | 18 ++-- compiler/rustc_ty_utils/src/consts.rs | 84 +++++++++++++++++++ compiler/rustc_ty_utils/src/lib.rs | 2 + src/test/ui/const-generics/issue-66451.rs | 28 +++++++ src/test/ui/const-generics/issue-66451.stderr | 20 +++++ 9 files changed, 144 insertions(+), 102 deletions(-) create mode 100644 compiler/rustc_ty_utils/src/consts.rs create mode 100644 src/test/ui/const-generics/issue-66451.rs create mode 100644 src/test/ui/const-generics/issue-66451.stderr diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index a1d2e5cf3ef12..bf65fdc54ca48 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -5,7 +5,6 @@ use rustc_middle::mir; use rustc_middle::mir::interpret::{EvalToValTreeResult, GlobalId}; use rustc_middle::ty::{self, TyCtxt}; use rustc_span::{source_map::DUMMY_SP, symbol::Symbol}; -use rustc_target::abi::VariantIdx; use crate::interpret::{ intern_const_alloc_recursive, ConstValue, InternKind, InterpCx, InterpResult, MemPlaceMeta, @@ -91,83 +90,6 @@ pub(crate) fn eval_to_valtree<'tcx>( } } -/// Tries to destructure constants of type Array or Adt into the constants -/// of its fields. -pub(crate) fn try_destructure_const<'tcx>( - tcx: TyCtxt<'tcx>, - const_: ty::Const<'tcx>, -) -> Option> { - if let ty::ConstKind::Value(valtree) = const_.kind() { - let branches = match valtree { - ty::ValTree::Branch(b) => b, - _ => return None, - }; - - let (fields, variant) = match const_.ty().kind() { - ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { - // construct the consts for the elements of the array/slice - let field_consts = branches - .iter() - .map(|b| { - tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty }) - }) - .collect::>(); - debug!(?field_consts); - - (field_consts, None) - } - ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"), - ty::Adt(def, substs) => { - let variant_idx = if def.is_enum() { - VariantIdx::from_u32(branches[0].unwrap_leaf().try_to_u32().ok()?) - } else { - VariantIdx::from_u32(0) - }; - let fields = &def.variant(variant_idx).fields; - let mut field_consts = Vec::with_capacity(fields.len()); - - // Note: First element inValTree corresponds to variant of enum - let mut valtree_idx = if def.is_enum() { 1 } else { 0 }; - for field in fields { - let field_ty = field.ty(tcx, substs); - let field_valtree = branches[valtree_idx]; // first element of branches is variant - let field_const = tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Value(field_valtree), - ty: field_ty, - }); - field_consts.push(field_const); - valtree_idx += 1; - } - debug!(?field_consts); - - (field_consts, Some(variant_idx)) - } - ty::Tuple(elem_tys) => { - let fields = elem_tys - .iter() - .enumerate() - .map(|(i, elem_ty)| { - let elem_valtree = branches[i]; - tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Value(elem_valtree), - ty: elem_ty, - }) - }) - .collect::>(); - - (fields, None) - } - _ => bug!("cannot destructure constant {:?}", const_), - }; - - let fields = tcx.arena.alloc_from_iter(fields.into_iter()); - - Some(ty::DestructuredConst { variant, fields }) - } else { - None - } -} - #[instrument(skip(tcx), level = "debug")] pub(crate) fn try_destructure_mir_constant<'tcx>( tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs index 64a74e9d7e206..5bf91879066f4 100644 --- a/compiler/rustc_const_eval/src/lib.rs +++ b/compiler/rustc_const_eval/src/lib.rs @@ -42,7 +42,6 @@ pub fn provide(providers: &mut Providers) { providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider; providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider; providers.const_caller_location = const_eval::const_caller_location; - providers.try_destructure_const = |tcx, val| const_eval::try_destructure_const(tcx, val); providers.eval_to_valtree = |tcx, param_env_and_value| { let (param_env, raw) = param_env_and_value.into_parts(); const_eval::eval_to_valtree(tcx, param_env, raw) diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs index 4895b53bb2677..575147feebc94 100644 --- a/compiler/rustc_middle/src/mir/interpret/queries.rs +++ b/compiler/rustc_middle/src/mir/interpret/queries.rs @@ -205,14 +205,8 @@ impl<'tcx> TyCtxtEnsure<'tcx> { } impl<'tcx> TyCtxt<'tcx> { - /// Destructure a type-level constant ADT or array into its variant index and its field values. - /// Panics if the destructuring fails, use `try_destructure_const` for fallible version. - pub fn destructure_const(self, const_: ty::Const<'tcx>) -> ty::DestructuredConst<'tcx> { - self.try_destructure_const(const_).unwrap() - } - /// Destructure a mir constant ADT or array into its variant index and its field values. - /// Panics if the destructuring fails, use `try_destructure_const` for fallible version. + /// Panics if the destructuring fails, use `try_destructure_mir_constant` for fallible version. pub fn destructure_mir_constant( self, param_env: ty::ParamEnv<'tcx>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2e68fc8a7c050..b07916d3bbc5a 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -978,11 +978,8 @@ rustc_queries! { desc { "converting type-level constant value to mir constant value"} } - /// Destructure a constant ADT or array into its variant index and its - /// field values or return `None` if constant is invalid. - /// - /// Use infallible `TyCtxt::destructure_const` when you know that constant is valid. - query try_destructure_const(key: ty::Const<'tcx>) -> Option> { + /// Destructure a type-level constant ADT or array into its variant index and its field values. + query destructure_const(key: ty::Const<'tcx>) -> ty::DestructuredConst<'tcx> { desc { "destructuring type level constant"} } diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index c56909ba18b14..7f3b0fdccc6f1 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1447,7 +1447,11 @@ pub trait PrettyPrinter<'tcx>: p!(write("{:?}", String::from_utf8_lossy(bytes))); return Ok(self); } - _ => {} + _ => { + p!("&"); + p!(pretty_print_const_valtree(valtree, *inner_ty, print_ty)); + return Ok(self); + } }, (ty::ValTree::Branch(_), ty::Array(t, _)) if *t == u8_type => { let bytes = valtree.try_to_raw_bytes(self.tcx(), *t).unwrap_or_else(|| { @@ -1459,16 +1463,8 @@ pub trait PrettyPrinter<'tcx>: } // Aggregates, printed as array/tuple/struct/variant construction syntax. (ty::ValTree::Branch(_), ty::Array(..) | ty::Tuple(..) | ty::Adt(..)) => { - let Some(contents) = self.tcx().try_destructure_const( - ty::Const::from_value(self.tcx(), valtree, ty) - ) else { - // Fall back to debug pretty printing for invalid constants. - p!(write("{:?}", valtree)); - if print_ty { - p!(": ", print(ty)); - } - return Ok(self); - }; + let contents = + self.tcx().destructure_const(ty::Const::from_value(self.tcx(), valtree, ty)); let fields = contents.fields.iter().copied(); match *ty.kind() { ty::Array(..) => { diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs new file mode 100644 index 0000000000000..22cfd7e19853e --- /dev/null +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -0,0 +1,84 @@ +use rustc_middle::ty::{self, TyCtxt}; +use rustc_target::abi::VariantIdx; + +/// Tries to destructure constants of type Array or Adt into the constants +/// of its fields. +pub(crate) fn destructure_const<'tcx>( + tcx: TyCtxt<'tcx>, + const_: ty::Const<'tcx>, +) -> ty::DestructuredConst<'tcx> { + if let ty::ConstKind::Value(valtree) = const_.kind() { + let branches = match valtree { + ty::ValTree::Branch(b) => b, + _ => bug!("cannot destructure constant {:?}", const_), + }; + + let (fields, variant) = match const_.ty().kind() { + ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { + // construct the consts for the elements of the array/slice + let field_consts = branches + .iter() + .map(|b| { + tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty }) + }) + .collect::>(); + debug!(?field_consts); + + (field_consts, None) + } + ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"), + ty::Adt(def, substs) => { + let variant_idx = if def.is_enum() { + VariantIdx::from_u32(branches[0].unwrap_leaf().try_to_u32().unwrap()) + } else { + VariantIdx::from_u32(0) + }; + let fields = &def.variant(variant_idx).fields; + let mut field_consts = Vec::with_capacity(fields.len()); + + // Note: First element inValTree corresponds to variant of enum + let mut valtree_idx = if def.is_enum() { 1 } else { 0 }; + for field in fields { + let field_ty = field.ty(tcx, substs); + let field_valtree = branches[valtree_idx]; // first element of branches is variant + let field_const = tcx.mk_const(ty::ConstS { + kind: ty::ConstKind::Value(field_valtree), + ty: field_ty, + }); + field_consts.push(field_const); + valtree_idx += 1; + } + debug!(?field_consts); + + (field_consts, Some(variant_idx)) + } + ty::Tuple(elem_tys) => { + let fields = elem_tys + .iter() + .enumerate() + .map(|(i, elem_ty)| { + let elem_valtree = branches[i]; + tcx.mk_const(ty::ConstS { + kind: ty::ConstKind::Value(elem_valtree), + ty: elem_ty, + }) + }) + .collect::>(); + + (fields, None) + } + _ => bug!("cannot destructure constant {:?}", const_), + }; + + let fields = tcx.arena.alloc_from_iter(fields.into_iter()); + + ty::DestructuredConst { variant, fields } + } else { + bug!("cannot destructure constant {:?}", const_) + } +} + +pub fn provide(providers: &mut ty::query::Providers) { + *providers = + ty::query::Providers { destructure_const, ..*providers }; +} diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 484967bbef8ce..a27cb7cf07e72 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -18,6 +18,7 @@ use rustc_middle::ty::query::Providers; mod assoc; mod common_traits; +pub mod consts; pub mod instance; mod needs_drop; pub mod representability; @@ -26,6 +27,7 @@ mod ty; pub fn provide(providers: &mut Providers) { assoc::provide(providers); common_traits::provide(providers); + consts::provide(providers); needs_drop::provide(providers); ty::provide(providers); instance::provide(providers); diff --git a/src/test/ui/const-generics/issue-66451.rs b/src/test/ui/const-generics/issue-66451.rs new file mode 100644 index 0000000000000..76505d1887594 --- /dev/null +++ b/src/test/ui/const-generics/issue-66451.rs @@ -0,0 +1,28 @@ +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +#[derive(Debug, PartialEq, Eq)] +struct Foo { + value: i32, + nested: &'static Bar, +} + +#[derive(Debug, PartialEq, Eq)] +struct Bar(T); + +struct Test; + +fn main() { + let x: Test<{ + Foo { + value: 3, + nested: &Bar(4), + } + }> = Test; + let y: Test<{ + Foo { + value: 3, + nested: &Bar(5), + } + }> = x; //~ ERROR mismatched types +} diff --git a/src/test/ui/const-generics/issue-66451.stderr b/src/test/ui/const-generics/issue-66451.stderr new file mode 100644 index 0000000000000..b691eac4f2d0e --- /dev/null +++ b/src/test/ui/const-generics/issue-66451.stderr @@ -0,0 +1,20 @@ +error[E0308]: mismatched types + --> $DIR/issue-66451.rs:27:10 + | +LL | let y: Test<{ + | ____________- +LL | | Foo { +LL | | value: 3, +LL | | nested: &Bar(5), +LL | | } +LL | | }> = x; + | | - ^ expected `Foo { value: 3_i32, nested: &Bar::(5_i32) }`, found `Foo { value: 3_i32, nested: &Bar::(4_i32) }` + | |______| + | expected due to this + | + = note: expected struct `Test(5_i32) }>` + found struct `Test(4_i32) }>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 080525229b9830c727cf447236deb7bdae7d5814 Mon Sep 17 00:00:00 2001 From: Dominik Stolz Date: Tue, 28 Jun 2022 22:45:05 +0200 Subject: [PATCH 04/17] Make consts mod private --- compiler/rustc_ty_utils/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index a27cb7cf07e72..7624d31b40bc7 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -18,7 +18,7 @@ use rustc_middle::ty::query::Providers; mod assoc; mod common_traits; -pub mod consts; +mod consts; pub mod instance; mod needs_drop; pub mod representability; From 053f48d91f3529a3aa1c82a1e96e9b77ef7edf30 Mon Sep 17 00:00:00 2001 From: Dominik Stolz Date: Tue, 28 Jun 2022 23:26:54 +0200 Subject: [PATCH 05/17] Address code review comments --- compiler/rustc_ty_utils/src/consts.rs | 119 ++++++++++------------ src/test/ui/const-generics/issue-66451.rs | 2 +- 2 files changed, 57 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 22cfd7e19853e..5f7cafe2722fd 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -1,84 +1,77 @@ use rustc_middle::ty::{self, TyCtxt}; use rustc_target::abi::VariantIdx; -/// Tries to destructure constants of type Array or Adt into the constants +use std::iter; + +/// Tries to destructure array, ADT or tuple constants into the constants /// of its fields. pub(crate) fn destructure_const<'tcx>( tcx: TyCtxt<'tcx>, const_: ty::Const<'tcx>, ) -> ty::DestructuredConst<'tcx> { - if let ty::ConstKind::Value(valtree) = const_.kind() { - let branches = match valtree { - ty::ValTree::Branch(b) => b, - _ => bug!("cannot destructure constant {:?}", const_), - }; + let ty::ConstKind::Value(valtree) = const_.kind() else { + bug!("cannot destructure constant {:?}", const_) + }; - let (fields, variant) = match const_.ty().kind() { - ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { - // construct the consts for the elements of the array/slice - let field_consts = branches - .iter() - .map(|b| { - tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty }) - }) - .collect::>(); - debug!(?field_consts); + let branches = match valtree { + ty::ValTree::Branch(b) => b, + _ => bug!("cannot destructure constant {:?}", const_), + }; - (field_consts, None) - } - ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"), - ty::Adt(def, substs) => { - let variant_idx = if def.is_enum() { - VariantIdx::from_u32(branches[0].unwrap_leaf().try_to_u32().unwrap()) - } else { - VariantIdx::from_u32(0) - }; - let fields = &def.variant(variant_idx).fields; - let mut field_consts = Vec::with_capacity(fields.len()); + let (fields, variant) = match const_.ty().kind() { + ty::Array(inner_ty, _) | ty::Slice(inner_ty) => { + // construct the consts for the elements of the array/slice + let field_consts = branches + .iter() + .map(|b| tcx.mk_const(ty::ConstS { kind: ty::ConstKind::Value(*b), ty: *inner_ty })) + .collect::>(); + debug!(?field_consts); - // Note: First element inValTree corresponds to variant of enum - let mut valtree_idx = if def.is_enum() { 1 } else { 0 }; - for field in fields { - let field_ty = field.ty(tcx, substs); - let field_valtree = branches[valtree_idx]; // first element of branches is variant - let field_const = tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Value(field_valtree), - ty: field_ty, - }); - field_consts.push(field_const); - valtree_idx += 1; - } - debug!(?field_consts); + (field_consts, None) + } + ty::Adt(def, _) if def.variants().is_empty() => bug!("unreachable"), + ty::Adt(def, substs) => { + let (variant_idx, branches) = if def.is_enum() { + let (head, rest) = branches.split_first().unwrap(); + (VariantIdx::from_u32(head.unwrap_leaf().try_to_u32().unwrap()), rest) + } else { + (VariantIdx::from_u32(0), branches) + }; + let fields = &def.variant(variant_idx).fields; + let mut field_consts = Vec::with_capacity(fields.len()); - (field_consts, Some(variant_idx)) + for (field, field_valtree) in iter::zip(fields, branches) { + let field_ty = field.ty(tcx, substs); + let field_const = tcx.mk_const(ty::ConstS { + kind: ty::ConstKind::Value(*field_valtree), + ty: field_ty, + }); + field_consts.push(field_const); } - ty::Tuple(elem_tys) => { - let fields = elem_tys - .iter() - .enumerate() - .map(|(i, elem_ty)| { - let elem_valtree = branches[i]; - tcx.mk_const(ty::ConstS { - kind: ty::ConstKind::Value(elem_valtree), - ty: elem_ty, - }) + debug!(?field_consts); + + (field_consts, Some(variant_idx)) + } + ty::Tuple(elem_tys) => { + let fields = iter::zip(*elem_tys, branches) + .map(|(elem_ty, elem_valtree)| { + tcx.mk_const(ty::ConstS { + kind: ty::ConstKind::Value(*elem_valtree), + ty: elem_ty, }) - .collect::>(); + }) + .collect::>(); - (fields, None) - } - _ => bug!("cannot destructure constant {:?}", const_), - }; + (fields, None) + } + _ => bug!("cannot destructure constant {:?}", const_), + }; - let fields = tcx.arena.alloc_from_iter(fields.into_iter()); + let fields = tcx.arena.alloc_from_iter(fields.into_iter()); - ty::DestructuredConst { variant, fields } - } else { - bug!("cannot destructure constant {:?}", const_) - } + ty::DestructuredConst { variant, fields } } pub fn provide(providers: &mut ty::query::Providers) { - *providers = - ty::query::Providers { destructure_const, ..*providers }; + *providers = ty::query::Providers { destructure_const, ..*providers }; } diff --git a/src/test/ui/const-generics/issue-66451.rs b/src/test/ui/const-generics/issue-66451.rs index 76505d1887594..3335f7d598480 100644 --- a/src/test/ui/const-generics/issue-66451.rs +++ b/src/test/ui/const-generics/issue-66451.rs @@ -17,7 +17,7 @@ fn main() { Foo { value: 3, nested: &Bar(4), - } + } }> = Test; let y: Test<{ Foo { From f97326de454583d36fef2efbfeb1ea384b9e9a50 Mon Sep 17 00:00:00 2001 From: Yan Chen Date: Tue, 28 Jun 2022 12:46:42 -0700 Subject: [PATCH 06/17] Fix #98260, added the test case --- compiler/rustc_typeck/src/variance/mod.rs | 5 +++++ src/test/ui/typeck/issue-98260.rs | 9 +++++++++ src/test/ui/typeck/issue-98260.stderr | 12 ++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 src/test/ui/typeck/issue-98260.rs create mode 100644 src/test/ui/typeck/issue-98260.stderr diff --git a/compiler/rustc_typeck/src/variance/mod.rs b/compiler/rustc_typeck/src/variance/mod.rs index e622192f2c94d..82103c5a03b6e 100644 --- a/compiler/rustc_typeck/src/variance/mod.rs +++ b/compiler/rustc_typeck/src/variance/mod.rs @@ -37,6 +37,11 @@ fn crate_variances(tcx: TyCtxt<'_>, (): ()) -> CrateVariancesMap<'_> { } fn variances_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[ty::Variance] { + // Skip items with no generics - there's nothing to infer in them. + if tcx.generics_of(item_def_id).count() == 0 { + return &[]; + } + match tcx.def_kind(item_def_id) { DefKind::Fn | DefKind::AssocFn diff --git a/src/test/ui/typeck/issue-98260.rs b/src/test/ui/typeck/issue-98260.rs new file mode 100644 index 0000000000000..cf48294e1997f --- /dev/null +++ b/src/test/ui/typeck/issue-98260.rs @@ -0,0 +1,9 @@ +fn main() {} +trait A { + fn a(aa: B) -> Result<_, B> { + //~^ ERROR: the placeholder `_` is not allowed within types on item signatures for return types [E0121] + Ok(()) + } +} + +enum B {} diff --git a/src/test/ui/typeck/issue-98260.stderr b/src/test/ui/typeck/issue-98260.stderr new file mode 100644 index 0000000000000..08a1d17e244a8 --- /dev/null +++ b/src/test/ui/typeck/issue-98260.stderr @@ -0,0 +1,12 @@ +error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types + --> $DIR/issue-98260.rs:3:27 + | +LL | fn a(aa: B) -> Result<_, B> { + | -------^---- + | | | + | | not allowed in type signatures + | help: replace with the correct return type: `Result<(), B>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0121`. From 78c9790e2aafd321c2086e1b5b0e78a51533a665 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Tue, 28 Jun 2022 15:31:42 -0700 Subject: [PATCH 07/17] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index a5e08c4703f20..dbff32b27893b 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit a5e08c4703f202e30cdaf80ca3e7c00baa59c496 +Subproject commit dbff32b27893b899ae2397f3d56d1be111041d56 From cec6988a07d30843f4b1c038fb6ff62f15d1a5e1 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Jun 2022 14:16:05 -0700 Subject: [PATCH 08/17] rustdoc: fix help menu popover toggling --- src/librustdoc/html/static/js/main.js | 3 +++ src/test/rustdoc-gui/pocket-menu.goml | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 70dbfd4442540..2d2de7db0c97c 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -926,6 +926,7 @@ function loadCss(cssFileName) { function showHelp() { const menu = getHelpMenu(true); if (menu.style.display === "none") { + window.hidePopoverMenus(); menu.style.display = ""; } } @@ -939,6 +940,8 @@ function loadCss(cssFileName) { const shouldShowHelp = menu.style.display === "none"; if (shouldShowHelp) { showHelp(); + } else { + window.hidePopoverMenus(); } }); diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml index ba2986e969a35..54f3790a76521 100644 --- a/src/test/rustdoc-gui/pocket-menu.goml +++ b/src/test/rustdoc-gui/pocket-menu.goml @@ -24,6 +24,11 @@ click: "#help-button" assert-css: ("#help-button .popover", {"display": "block"}) assert-css: ("#settings-menu .popover", {"display": "none"}) +// Now verify that clicking the help menu again closes it. +click: "#help-button" +assert-css: ("#help-button .popover", {"display": "none"}) +assert-css: ("#settings-menu .popover", {"display": "none"}) + // We check the borders color now: // Ayu theme From cb8a7388fa0106793c3ea709528fa1408c7cf87b Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Jun 2022 14:56:24 -0700 Subject: [PATCH 09/17] rustdoc: fix keyboard shortcuts bug in settings menu This commit fixes the keyboard shorts code to call localStorage every time a key is pressed. This matters because you're supposed to be able to change a setting and have it immediately take effect. --- src/librustdoc/html/static/js/main.js | 2 +- src/test/rustdoc-gui/settings.goml | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 2d2de7db0c97c..789e7d298fa98 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -412,9 +412,9 @@ function loadCss(cssFileName) { window.hidePopoverMenus(); } - const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; function handleShortcut(ev) { // Don't interfere with browser shortcuts + const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; if (ev.ctrlKey || ev.altKey || ev.metaKey || disableShortcuts) { return; } diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml index 237a4751a8d66..a43c712ef9a02 100644 --- a/src/test/rustdoc-gui/settings.goml +++ b/src/test/rustdoc-gui/settings.goml @@ -121,6 +121,17 @@ local-storage: {"rustdoc-disable-shortcuts": "false"} click: ".setting-line:last-child .toggle .label" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} +// Make sure that "Disable keyboard shortcuts" actually took effect. +press-key: "?" +wait-for-css: ("#settings-menu .popover", {"display": "block"}) + +// Now turn keyboard shortcuts back on, and see if they work. +click: ".setting-line:last-child .toggle .label" +assert-local-storage: {"rustdoc-disable-shortcuts": "false"} +press-key: "?" +wait-for-css: ("#help-button .popover", {"display": "block"}) +assert-css: ("#settings-menu .popover", {"display": "none"}) + // Now we go to the settings page to check that the CSS is loaded as expected. goto: file://|DOC_PATH|/settings.html wait-for: "#settings" From f5f42a8cba22fe1616b33cbedf2adc9bf01056b0 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Jun 2022 15:06:48 -0700 Subject: [PATCH 10/17] rustdoc: make keyboard commands work when checkboxes are selected --- src/librustdoc/html/static/js/main.js | 3 ++- src/test/rustdoc-gui/settings.goml | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 789e7d298fa98..c33e272774438 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -419,7 +419,8 @@ function loadCss(cssFileName) { return; } - if (document.activeElement.tagName === "INPUT") { + if (document.activeElement.tagName === "INPUT" && + document.activeElement.type !== "checkbox") { switch (getVirtualKey(ev)) { case "Escape": handleEscape(ev); diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml index a43c712ef9a02..49478775b0582 100644 --- a/src/test/rustdoc-gui/settings.goml +++ b/src/test/rustdoc-gui/settings.goml @@ -122,6 +122,7 @@ click: ".setting-line:last-child .toggle .label" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} // Make sure that "Disable keyboard shortcuts" actually took effect. +// The help popover won't exist yet. press-key: "?" wait-for-css: ("#settings-menu .popover", {"display": "block"}) From ccea908c17c835a8466334baacbcb4052347802e Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 28 Jun 2022 17:30:58 -0700 Subject: [PATCH 11/17] rustdoc: add assertion for missing popover div --- src/test/rustdoc-gui/settings.goml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/test/rustdoc-gui/settings.goml b/src/test/rustdoc-gui/settings.goml index 49478775b0582..c402c7991c8bb 100644 --- a/src/test/rustdoc-gui/settings.goml +++ b/src/test/rustdoc-gui/settings.goml @@ -122,13 +122,15 @@ click: ".setting-line:last-child .toggle .label" assert-local-storage: {"rustdoc-disable-shortcuts": "true"} // Make sure that "Disable keyboard shortcuts" actually took effect. -// The help popover won't exist yet. +press-key: "Escape" press-key: "?" +assert-false: "#help-button .popover" wait-for-css: ("#settings-menu .popover", {"display": "block"}) // Now turn keyboard shortcuts back on, and see if they work. click: ".setting-line:last-child .toggle .label" assert-local-storage: {"rustdoc-disable-shortcuts": "false"} +press-key: "Escape" press-key: "?" wait-for-css: ("#help-button .popover", {"display": "block"}) assert-css: ("#settings-menu .popover", {"display": "none"}) From 83addf2540ce7ce7d0f875fdbe2a7cd0e7f52d97 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 29 Jun 2022 01:09:02 +0200 Subject: [PATCH 12/17] alloc: fix `no_global_oom_handling` warnings Rust 1.62.0 introduced a couple new `unused_imports` warnings in `no_global_oom_handling` builds, making a total of 5 warnings: ```txt warning: unused import: `Unsize` --> library/alloc/src/boxed/thin.rs:6:33 | 6 | use core::marker::{PhantomData, Unsize}; | ^^^^^^ | = note: `#[warn(unused_imports)]` on by default warning: unused import: `from_fn` --> library/alloc/src/string.rs:51:18 | 51 | use core::iter::{from_fn, FusedIterator}; | ^^^^^^^ warning: unused import: `core::ops::Deref` --> library/alloc/src/vec/into_iter.rs:12:5 | 12 | use core::ops::Deref; | ^^^^^^^^^^^^^^^^ warning: associated function `shrink` is never used --> library/alloc/src/raw_vec.rs:424:8 | 424 | fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> { | ^^^^^^ | = note: `#[warn(dead_code)]` on by default warning: associated function `forget_remaining_elements` is never used --> library/alloc/src/vec/into_iter.rs:126:19 | 126 | pub(crate) fn forget_remaining_elements(&mut self) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ ``` This patch cleans them so that projects compiling `alloc` without infallible allocations do not see the warnings. It also enables the use of `-Dwarnings`. The couple `dead_code` ones may be reverted when some fallible allocation support starts using them. Signed-off-by: Miguel Ojeda --- library/alloc/src/boxed/thin.rs | 4 +++- library/alloc/src/raw_vec.rs | 1 + library/alloc/src/string.rs | 4 ++-- library/alloc/src/vec/into_iter.rs | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs index 203e5dff0c77f..09308d4d0906d 100644 --- a/library/alloc/src/boxed/thin.rs +++ b/library/alloc/src/boxed/thin.rs @@ -3,7 +3,9 @@ // by matthieu-m use crate::alloc::{self, Layout, LayoutError}; use core::fmt::{self, Debug, Display, Formatter}; -use core::marker::{PhantomData, Unsize}; +use core::marker::PhantomData; +#[cfg(not(no_global_oom_handling))] +use core::marker::Unsize; use core::mem; use core::ops::{Deref, DerefMut}; use core::ptr::Pointee; diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs index 4be5f6cf9ca51..b0f4529abdfa5 100644 --- a/library/alloc/src/raw_vec.rs +++ b/library/alloc/src/raw_vec.rs @@ -421,6 +421,7 @@ impl RawVec { Ok(()) } + #[cfg(not(no_global_oom_handling))] fn shrink(&mut self, cap: usize) -> Result<(), TryReserveError> { assert!(cap <= self.capacity(), "Tried to shrink to a larger capacity"); diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index 8883880726594..b1513e5e0f31c 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -46,9 +46,9 @@ use core::char::{decode_utf16, REPLACEMENT_CHARACTER}; use core::fmt; use core::hash; +use core::iter::FusedIterator; #[cfg(not(no_global_oom_handling))] -use core::iter::FromIterator; -use core::iter::{from_fn, FusedIterator}; +use core::iter::{from_fn, FromIterator}; #[cfg(not(no_global_oom_handling))] use core::ops::Add; #[cfg(not(no_global_oom_handling))] diff --git a/library/alloc/src/vec/into_iter.rs b/library/alloc/src/vec/into_iter.rs index 9b84a1d9b4b64..28979457b7fd3 100644 --- a/library/alloc/src/vec/into_iter.rs +++ b/library/alloc/src/vec/into_iter.rs @@ -9,6 +9,7 @@ use core::iter::{ }; use core::marker::PhantomData; use core::mem::{self, ManuallyDrop}; +#[cfg(not(no_global_oom_handling))] use core::ops::Deref; use core::ptr::{self, NonNull}; use core::slice::{self}; @@ -123,6 +124,7 @@ impl IntoIter { } /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed. + #[cfg(not(no_global_oom_handling))] pub(crate) fn forget_remaining_elements(&mut self) { self.ptr = self.end; } From 60dc54e29e2589ad21413db8f81518174b2fe604 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 29 Jun 2022 04:02:21 +0200 Subject: [PATCH 13/17] alloc: ensure `no_global_oom_handling` builds are warning-free Rust 1.62.0 introduced a couple new `unused_imports` warnings in `no_global_oom_handling` builds, making a total of 5 warnings. To avoid accumulating more over time, let's keep the builds warning-free. This ensures projects compiling `alloc` without infallible allocations do not see the warnings in the future and that they can keep enabling `-Dwarnings`. Signed-off-by: Miguel Ojeda --- src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile b/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile index 6e25eb7e45945..eb6ad9bd1a7da 100644 --- a/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile +++ b/src/test/run-make-fulldeps/alloc-no-oom-handling/Makefile @@ -1,4 +1,4 @@ -include ../tools.mk all: - $(RUSTC) --edition=2021 --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_global_oom_handling + $(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_global_oom_handling From a84e19d444ffdaf0795e186e1fe55f8578f10be1 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Wed, 29 Jun 2022 07:22:21 +0000 Subject: [PATCH 14/17] Unbreak stage1 tests via ignore-stage1 in `proc-macro/invalid-punct-ident-1.rs`. --- .../ui/proc-macro/invalid-punct-ident-1.rs | 18 +++++------------- .../ui/proc-macro/invalid-punct-ident-1.stderr | 2 +- 2 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.rs b/src/test/ui/proc-macro/invalid-punct-ident-1.rs index ecbb6ebf55b9a..fdf3ca2e261b6 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-1.rs +++ b/src/test/ui/proc-macro/invalid-punct-ident-1.rs @@ -1,17 +1,9 @@ // aux-build:invalid-punct-ident.rs -// rustc-env:RUST_BACKTRACE=0 - -// FIXME https://github.com/rust-lang/rust/issues/59998 -// normalize-stderr-test "thread.*panicked.*proc_macro.*lib.rs.*\n" -> "" -// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> "" -// normalize-stderr-test "\nerror: internal compiler error.*\n\n" -> "" -// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> "" -// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> "" -// normalize-stderr-test "note: compiler flags.*\n\n" -> "" -// normalize-stderr-test "note: rustc.*running on.*\n\n" -> "" -// normalize-stderr-test "query stack during panic:\n" -> "" -// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> "" -// normalize-stderr-test "end of query stack\n" -> "" +// ignore-stage1 +// only-linux +// +// FIXME: This should be a normal (stage1, all platforms) test in +// src/test/ui/proc-macro once issue #59998 is fixed. #[macro_use] extern crate invalid_punct_ident; diff --git a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr index eaf41c080faf4..bb0a48cb16b8d 100644 --- a/src/test/ui/proc-macro/invalid-punct-ident-1.stderr +++ b/src/test/ui/proc-macro/invalid-punct-ident-1.stderr @@ -1,5 +1,5 @@ error: proc macro panicked - --> $DIR/invalid-punct-ident-1.rs:19:1 + --> $DIR/invalid-punct-ident-1.rs:11:1 | LL | invalid_punct!(); | ^^^^^^^^^^^^^^^^ From d048b15216a14711b386ac5322cf24583df5ed3d Mon Sep 17 00:00:00 2001 From: Dominik Stolz Date: Wed, 29 Jun 2022 10:30:47 +0200 Subject: [PATCH 15/17] Improve doc comment of destructure_const --- compiler/rustc_middle/src/query/mod.rs | 3 ++- compiler/rustc_ty_utils/src/consts.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b07916d3bbc5a..a1065eef8509d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -978,7 +978,8 @@ rustc_queries! { desc { "converting type-level constant value to mir constant value"} } - /// Destructure a type-level constant ADT or array into its variant index and its field values. + /// Destructures array, ADT or tuple constants into the constants + /// of their fields. query destructure_const(key: ty::Const<'tcx>) -> ty::DestructuredConst<'tcx> { desc { "destructuring type level constant"} } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index 5f7cafe2722fd..0b83cdb78dce7 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -3,8 +3,8 @@ use rustc_target::abi::VariantIdx; use std::iter; -/// Tries to destructure array, ADT or tuple constants into the constants -/// of its fields. +/// Destructures array, ADT or tuple constants into the constants +/// of their fields. pub(crate) fn destructure_const<'tcx>( tcx: TyCtxt<'tcx>, const_: ty::Const<'tcx>, From 3cbf864d4303548e42514be6c216ba0f18acb543 Mon Sep 17 00:00:00 2001 From: Chris Denton Date: Wed, 29 Jun 2022 09:36:12 +0100 Subject: [PATCH 16/17] Use verbose help for deprecation suggestion --- compiler/rustc_middle/src/middle/stability.rs | 2 +- src/test/ui/deprecation/atomic_initializers.stderr | 6 +++++- ...ssue-84637-deprecated-associated-function.stderr | 13 +++++++++++-- src/test/ui/deprecation/suggestion.stderr | 13 +++++++++++-- 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index d23707a9d316e..802b7852bace1 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -150,7 +150,7 @@ pub fn deprecation_suggestion( span: Span, ) { if let Some(suggestion) = suggestion { - diag.span_suggestion( + diag.span_suggestion_verbose( span, &format!("replace the use of the deprecated {}", kind), suggestion, diff --git a/src/test/ui/deprecation/atomic_initializers.stderr b/src/test/ui/deprecation/atomic_initializers.stderr index eaf5c61b440bd..30fcc9de6181e 100644 --- a/src/test/ui/deprecation/atomic_initializers.stderr +++ b/src/test/ui/deprecation/atomic_initializers.stderr @@ -2,9 +2,13 @@ warning: use of deprecated constant `std::sync::atomic::ATOMIC_ISIZE_INIT`: the --> $DIR/atomic_initializers.rs:8:27 | LL | static FOO: AtomicIsize = ATOMIC_ISIZE_INIT; - | ^^^^^^^^^^^^^^^^^ help: replace the use of the deprecated constant: `AtomicIsize::new(0)` + | ^^^^^^^^^^^^^^^^^ | = note: `#[warn(deprecated)]` on by default +help: replace the use of the deprecated constant + | +LL | static FOO: AtomicIsize = AtomicIsize::new(0); + | ~~~~~~~~~~~~~~~~~~~ warning: 1 warning emitted diff --git a/src/test/ui/deprecation/issue-84637-deprecated-associated-function.stderr b/src/test/ui/deprecation/issue-84637-deprecated-associated-function.stderr index e65d21bb09bbe..8d4529526e370 100644 --- a/src/test/ui/deprecation/issue-84637-deprecated-associated-function.stderr +++ b/src/test/ui/deprecation/issue-84637-deprecated-associated-function.stderr @@ -2,19 +2,28 @@ error: use of deprecated associated function `core::str::::trim_left`: --> $DIR/issue-84637-deprecated-associated-function.rs:6:21 | LL | let _foo = str::trim_left(" aoeu"); - | ^^^^^^^^^ help: replace the use of the deprecated associated function: `trim_start` + | ^^^^^^^^^ | note: the lint level is defined here --> $DIR/issue-84637-deprecated-associated-function.rs:3:9 | LL | #![deny(deprecated)] | ^^^^^^^^^^ +help: replace the use of the deprecated associated function + | +LL | let _foo = str::trim_start(" aoeu"); + | ~~~~~~~~~~ error: use of deprecated associated function `core::str::::trim_left`: superseded by `trim_start` --> $DIR/issue-84637-deprecated-associated-function.rs:8:26 | LL | let _bar = " aoeu".trim_left(); - | ^^^^^^^^^ help: replace the use of the deprecated associated function: `trim_start` + | ^^^^^^^^^ + | +help: replace the use of the deprecated associated function + | +LL | let _bar = " aoeu".trim_start(); + | ~~~~~~~~~~ error: aborting due to 2 previous errors diff --git a/src/test/ui/deprecation/suggestion.stderr b/src/test/ui/deprecation/suggestion.stderr index 8d1e108345f30..c5f2fc0912514 100644 --- a/src/test/ui/deprecation/suggestion.stderr +++ b/src/test/ui/deprecation/suggestion.stderr @@ -2,19 +2,28 @@ error: use of deprecated function `bar::deprecated`: replaced by `replacement` --> $DIR/suggestion.rs:42:10 | LL | bar::deprecated(); - | ^^^^^^^^^^ help: replace the use of the deprecated function: `replacement` + | ^^^^^^^^^^ | note: the lint level is defined here --> $DIR/suggestion.rs:8:9 | LL | #![deny(deprecated)] | ^^^^^^^^^^ +help: replace the use of the deprecated function + | +LL | bar::replacement(); + | ~~~~~~~~~~~ error: use of deprecated associated function `Foo::deprecated`: replaced by `replacement` --> $DIR/suggestion.rs:40:9 | LL | foo.deprecated(); - | ^^^^^^^^^^ help: replace the use of the deprecated associated function: `replacement` + | ^^^^^^^^^^ + | +help: replace the use of the deprecated associated function + | +LL | foo.replacement(); + | ~~~~~~~~~~~ error: aborting due to 2 previous errors From 6212e6b3396d8aeb5ab35f12caaf6eceea9b8836 Mon Sep 17 00:00:00 2001 From: Takayuki Maeda Date: Wed, 29 Jun 2022 21:16:43 +0900 Subject: [PATCH 17/17] avoid many `&str` to `String` conversions with `MultiSpan::push_span_label` --- compiler/rustc_expand/src/tests.rs | 2 +- .../nice_region_error/static_impl_trait.rs | 20 ++++++------------- .../trait_impl_difference.rs | 6 ++---- .../src/traits/error_reporting/mod.rs | 3 +-- .../src/thir/pattern/check_match.rs | 2 +- compiler/rustc_parse/src/parser/mod.rs | 11 ++++------ compiler/rustc_passes/src/check_attr.rs | 7 ++----- compiler/rustc_resolve/src/diagnostics.rs | 2 +- .../rustc_resolve/src/late/diagnostics.rs | 13 ++++-------- .../src/traits/error_reporting/suggestions.rs | 3 +-- compiler/rustc_typeck/src/astconv/generics.rs | 2 +- compiler/rustc_typeck/src/check/_match.rs | 12 ++++------- compiler/rustc_typeck/src/check/check.rs | 3 +-- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 2 +- .../rustc_typeck/src/check/method/suggest.rs | 12 +++++------ .../wrong_number_of_generic_args.rs | 2 +- 17 files changed, 38 insertions(+), 66 deletions(-) diff --git a/compiler/rustc_expand/src/tests.rs b/compiler/rustc_expand/src/tests.rs index 8b7153776e4dc..e44f060819633 100644 --- a/compiler/rustc_expand/src/tests.rs +++ b/compiler/rustc_expand/src/tests.rs @@ -136,7 +136,7 @@ fn test_harness(file_text: &str, span_labels: Vec, expected_output: & let mut msp = MultiSpan::from_span(primary_span); for span_label in span_labels { let span = make_span(&file_text, &span_label.start, &span_label.end); - msp.push_span_label(span, span_label.label.to_string()); + msp.push_span_label(span, span_label.label); println!("span: {:?} label: {:?}", span, span_label.label); println!("text: {:?}", source_map.span_to_snippet(span)); } diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 6935ce9710b6e..09430a135a337 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -194,10 +194,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if !v.0.is_empty() { span = v.0.clone().into(); for sp in v.0 { - span.push_span_label( - sp, - "`'static` requirement introduced here".to_string(), - ); + span.push_span_label(sp, "`'static` requirement introduced here"); } add_label = false; } @@ -205,13 +202,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { if add_label { span.push_span_label( fn_decl.output.span(), - "requirement introduced by this return type".to_string(), + "requirement introduced by this return type", ); } - span.push_span_label( - cause.span, - "because of this returned expression".to_string(), - ); + span.push_span_label(cause.span, "because of this returned expression"); err.span_note( span, "`'static` lifetime requirement introduced by the return type", @@ -523,13 +517,11 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { hir_v.visit_ty(&self_ty); for span in &traits { let mut multi_span: MultiSpan = vec![*span].into(); - multi_span.push_span_label( - *span, - "this has an implicit `'static` lifetime requirement".to_string(), - ); + multi_span + .push_span_label(*span, "this has an implicit `'static` lifetime requirement"); multi_span.push_span_label( ident.span, - "calling this method introduces the `impl`'s 'static` requirement".to_string(), + "calling this method introduces the `impl`'s 'static` requirement", ); err.span_note(multi_span, "the used `impl` has a `'static` requirement"); err.span_suggestion_verbose( diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs index 17d4bb1bcbe35..f6b49e41d4c47 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs @@ -128,10 +128,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { } let mut type_param_span: MultiSpan = visitor.types.to_vec().into(); for &span in &visitor.types { - type_param_span.push_span_label( - span, - "consider borrowing this type parameter in the trait".to_string(), - ); + type_param_span + .push_span_label(span, "consider borrowing this type parameter in the trait"); } err.note(&format!("expected `{}`\n found `{}`", expected, found)); diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index d297640c14027..4eafa3329c36a 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -85,8 +85,7 @@ pub fn report_object_safety_error<'tcx>( let has_multi_span = !multi_span.is_empty(); let mut note_span = MultiSpan::from_spans(multi_span.clone()); if let (Some(trait_span), true) = (trait_span, has_multi_span) { - note_span - .push_span_label(trait_span, "this trait cannot be made into an object...".to_string()); + note_span.push_span_label(trait_span, "this trait cannot be made into an object..."); } for (span, msg) in iter::zip(multi_span, messages) { note_span.push_span_label(span, msg); diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 76333b755b747..61ac3d14e50e2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -947,7 +947,7 @@ fn adt_defined_here<'p, 'tcx>( span.push_span_label(def_span, String::new()); for pat in spans { - span.push_span_label(pat, "not covered".to_string()); + span.push_span_label(pat, "not covered"); } err.span_note(span, &format!("`{}` defined here", ty)); } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 6d6667717f0a3..1bdc980bfaf2d 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -887,22 +887,19 @@ impl<'a> Parser<'a> { let mut first_note = MultiSpan::from(vec![initial_semicolon]); first_note.push_span_label( initial_semicolon, - "this `;` turns the preceding closure into a statement".to_string(), + "this `;` turns the preceding closure into a statement", ); first_note.push_span_label( closure_spans.body, - "this expression is a statement because of the trailing semicolon".to_string(), + "this expression is a statement because of the trailing semicolon", ); expect_err.span_note(first_note, "statement found outside of a block"); let mut second_note = MultiSpan::from(vec![closure_spans.whole_closure]); - second_note.push_span_label( - closure_spans.whole_closure, - "this is the parsed closure...".to_string(), - ); + second_note.push_span_label(closure_spans.whole_closure, "this is the parsed closure..."); second_note.push_span_label( following_token_span, - "...but likely you meant the closure to end here".to_string(), + "...but likely you meant the closure to end here", ); expect_err.span_note(second_note, "the closure body may be incorrectly delimited"); diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 536d45b2399b1..40545b19b24dc 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -857,11 +857,8 @@ impl CheckAttrVisitor<'_> { if let Some((prev_inline, prev_span)) = *specified_inline { if do_inline != prev_inline { let mut spans = MultiSpan::from_spans(vec![prev_span, meta.span()]); - spans.push_span_label(prev_span, String::from("this attribute...")); - spans.push_span_label( - meta.span(), - String::from("...conflicts with this attribute"), - ); + spans.push_span_label(prev_span, "this attribute..."); + spans.push_span_label(meta.span(), "...conflicts with this attribute"); self.tcx .sess .struct_span_err(spans, "conflicting doc inlining attributes") diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 86dbcba6c0d51..e8b7cee573490 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -2561,7 +2561,7 @@ fn show_candidates( let span = source_span[local_def_id]; let span = session.source_map().guess_head_span(span); let mut multi_span = MultiSpan::from_span(span); - multi_span.push_span_label(span, "not accessible".to_string()); + multi_span.push_span_label(span, "not accessible"); err.span_note(multi_span, &msg); } else { err.note(&msg); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 68bcba7147bba..2b4e64bddc24b 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -601,10 +601,8 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { }; multi_span.push_span_label(sp, msg); } - multi_span.push_span_label( - base_error.span, - "expected this type to be a trait...".to_string(), - ); + multi_span + .push_span_label(base_error.span, "expected this type to be a trait..."); err.span_help( multi_span, "`+` is used to constrain a \"trait object\" type with lifetimes or \ @@ -1227,17 +1225,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { let mut m: MultiSpan = non_visible_spans.clone().into(); non_visible_spans .into_iter() - .for_each(|s| m.push_span_label(s, "private field".to_string())); + .for_each(|s| m.push_span_label(s, "private field")); err.span_note(m, "constructor is not visible here due to private fields"); } return true; } - err.span_label( - span, - "constructor is not visible here due to private fields".to_string(), - ); + err.span_label(span, "constructor is not visible here due to private fields"); } ( Res::Def( diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index fbe66d7dcdd2b..dfbb47cf4c557 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -2204,8 +2204,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { _ => true, }; if !ident.span.overlaps(span) && !same_line { - multispan - .push_span_label(ident.span, "required by a bound in this".to_string()); + multispan.push_span_label(ident.span, "required by a bound in this"); } } let descr = format!("required by a bound in `{}`", item_name); diff --git a/compiler/rustc_typeck/src/astconv/generics.rs b/compiler/rustc_typeck/src/astconv/generics.rs index 60682aa343517..612dc38452188 100644 --- a/compiler/rustc_typeck/src/astconv/generics.rs +++ b/compiler/rustc_typeck/src/astconv/generics.rs @@ -645,7 +645,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { err.emit(); } else { let mut multispan = MultiSpan::from_span(span); - multispan.push_span_label(span_late, note.to_string()); + multispan.push_span_label(span_late, note); tcx.struct_span_lint_hir( LATE_BOUND_LIFETIME_ARGUMENTS, args.args[0].id(), diff --git a/compiler/rustc_typeck/src/check/_match.rs b/compiler/rustc_typeck/src/check/_match.rs index bbdf1dae4a904..035571c881c56 100644 --- a/compiler/rustc_typeck/src/check/_match.rs +++ b/compiler/rustc_typeck/src/check/_match.rs @@ -154,18 +154,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ret_span.push_span_label( expr.span, "this could be implicitly returned but it is a statement, not a \ - tail expression" - .to_owned(), - ); - ret_span.push_span_label( - ret, - "the `match` arms can conform to this return type".to_owned(), + tail expression", ); + ret_span + .push_span_label(ret, "the `match` arms can conform to this return type"); ret_span.push_span_label( semi_span, "the `match` is a statement because of this semicolon, consider \ - removing it" - .to_owned(), + removing it", ); err.span_note( ret_span, diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs index 45c011b78e388..2f5c81af18ba3 100644 --- a/compiler/rustc_typeck/src/check/check.rs +++ b/compiler/rustc_typeck/src/check/check.rs @@ -1591,8 +1591,7 @@ fn opaque_type_cycle_error(tcx: TyCtxt<'_>, def_id: LocalDefId, span: Span) -> E } else { let mut multispan: MultiSpan = spans.clone().into(); for span in spans { - multispan - .push_span_label(span, "this returned value is of `!` type".to_string()); + multispan.push_span_label(span, "this returned value is of `!` type"); } err.span_note(multispan, "these returned values have a concrete \"never\" type"); } diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index ea7ebdf91d012..d5075537cedda 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -1034,7 +1034,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); sp.push_span_label( rcvr.span, - "you probably want to use this value after calling the method...".to_string(), + "you probably want to use this value after calling the method...", ); err.span_note( sp, diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index 2326c4069e483..2c7ca2757604f 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -1768,7 +1768,7 @@ fn label_fn_like<'tcx>( .flat_map(|id| tcx.hir().body(id).params); for param in params { - spans.push_span_label(param.span, String::new()); + spans.push_span_label(param.span, ""); } let def_kind = tcx.def_kind(def_id); diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 79a13ce2fcac9..fa5f0eff22329 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -638,7 +638,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let parent_trait_ref = data.parent_trait_pred; let path = parent_trait_ref.print_modifiers_and_trait_path(); let tr_self_ty = parent_trait_ref.skip_binder().self_ty(); - let unsatisfied_msg = "unsatisfied trait bound introduced here".to_string(); + let unsatisfied_msg = "unsatisfied trait bound introduced here"; let derive_msg = "unsatisfied trait bound introduced in this `derive` macro"; match self.tcx.hir().get_if_local(impl_def_id) { @@ -655,7 +655,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let span = ident.span.ctxt().outer_expn_data().call_site; let mut spans: MultiSpan = span.into(); - spans.push_span_label(span, derive_msg.to_string()); + spans.push_span_label(span, derive_msg); let entry = spanned_predicates.entry(spans); entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); } @@ -678,7 +678,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { let span = self_ty.span.ctxt().outer_expn_data().call_site; let mut spans: MultiSpan = span.into(); - spans.push_span_label(span, derive_msg.to_string()); + spans.push_span_label(span, derive_msg); let entry = spanned_predicates.entry(spans); entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); } @@ -706,7 +706,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } else { ident.span.into() }; - spans.push_span_label(ident.span, "in this trait".to_string()); + spans.push_span_label(ident.span, "in this trait"); let entry = spanned_predicates.entry(spans); entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); } @@ -747,9 +747,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { spans.into() }; if let Some(trait_ref) = of_trait { - spans.push_span_label(trait_ref.path.span, String::new()); + spans.push_span_label(trait_ref.path.span, ""); } - spans.push_span_label(self_ty.span, String::new()); + spans.push_span_label(self_ty.span, ""); let entry = spanned_predicates.entry(spans); entry.or_insert_with(|| (path, tr_self_ty, Vec::new())).2.push(p); diff --git a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs index 3224864e9b1fe..72a32dade4eef 100644 --- a/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs +++ b/compiler/rustc_typeck/src/structured_errors/wrong_number_of_generic_args.rs @@ -836,7 +836,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> { .take(bound) .map(|param| { let span = self.tcx.def_span(param.def_id); - spans.push_span_label(span, String::new()); + spans.push_span_label(span, ""); param }) .map(|param| format!("`{}`", param.name))