From 5dd073e7e1794bd5267051a3b3320139c98022c3 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Thu, 17 Nov 2022 09:24:19 +0100 Subject: [PATCH 01/19] Encourage developers not to use periods in target names They can cause issues in e.g. cargo. --- src/doc/rustc/src/target-tier-policy.md | 2 ++ src/tools/tier-check/src/main.rs | 18 +++++++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md index df9131ce84afd..95932db14e1f6 100644 --- a/src/doc/rustc/src/target-tier-policy.md +++ b/src/doc/rustc/src/target-tier-policy.md @@ -158,6 +158,8 @@ approved by the appropriate team for that shared code before acceptance. the name of the target makes people extremely likely to form incorrect beliefs about what it targets, the name should be changed or augmented to disambiguate it. + - If possible, use only letters, numbers, dashes and underscores for the name. + Periods (`.`) are known to cause issues in Cargo. - Tier 3 targets may have unusual requirements to build or use, but must not create legal issues or impose onerous legal terms for the Rust project or for Rust developers or users. diff --git a/src/tools/tier-check/src/main.rs b/src/tools/tier-check/src/main.rs index a41e2d6e3aa45..c74d37c61e887 100644 --- a/src/tools/tier-check/src/main.rs +++ b/src/tools/tier-check/src/main.rs @@ -44,7 +44,23 @@ fn main() { target, filename, src ); } - if !missing.is_empty() || !extra.is_empty() { + // Check target names for unwanted characters like `.` that can cause problems e.g. in Cargo. + // See also Tier 3 target policy. + // If desired, target names can ignore this check. + let ignore_target_names = + vec!["thumbv8m.base-none-eabi", "thumbv8m.main-none-eabi", "thumbv8m.main-none-eabihf"]; + let mut invalid_target_name_found = false; + for target in &target_list { + if !ignore_target_names.contains(target) + && !target.chars().all(|c| c.is_ascii_alphanumeric() || c == '-' || c == '_') + { + invalid_target_name_found = true; + eprintln!( + "error: Target name `{target}` contains other characters than ASCII alphanumeric (a-z, A-Z, 0-9), dash (-) or underscore (_)." + ); + } + } + if !missing.is_empty() || !extra.is_empty() || invalid_target_name_found { std::process::exit(1); } } From 9c3555d5c2dc3d1e5025c35db3873c2776054185 Mon Sep 17 00:00:00 2001 From: Florian Bartels Date: Thu, 17 Nov 2022 11:25:28 +0100 Subject: [PATCH 02/19] Remove periods from QNX/nto target names --- compiler/rustc_target/src/spec/mod.rs | 4 ++-- src/doc/rustc/src/platform-support.md | 4 ++-- src/doc/rustc/src/platform-support/nto-qnx.md | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 664592b02a124..9afbeadb1abf9 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -1244,8 +1244,8 @@ supported_targets! { ("mips64-openwrt-linux-musl", mips64_openwrt_linux_musl), - ("aarch64-unknown-nto-qnx7.1.0", aarch64_unknown_nto_qnx_710), - ("x86_64-pc-nto-qnx7.1.0", x86_64_pc_nto_qnx710), + ("aarch64-unknown-nto-qnx710", aarch64_unknown_nto_qnx_710), + ("x86_64-pc-nto-qnx710", x86_64_pc_nto_qnx710), } /// Cow-Vec-Str: Cow<'static, [Cow<'static, str>]> diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md index 28929acb9b48d..09d1dac7c58b5 100644 --- a/src/doc/rustc/src/platform-support.md +++ b/src/doc/rustc/src/platform-support.md @@ -214,7 +214,7 @@ target | std | host | notes [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ | | ARM64 SOLID with TOPPERS/ASP3 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * | | ARM64 Nintendo Switch, Horizon [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | -[`aarch64-unknown-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.1 RTOS | +[`aarch64-unknown-nto-qnx710`](platform-support/nto-qnx.md) | ? | | ARM64 QNX Neutrino 7.1 RTOS | `aarch64-unknown-freebsd` | ✓ | ✓ | ARM64 FreeBSD `aarch64-unknown-hermit` | ✓ | | ARM64 HermitCore `aarch64-unknown-linux-gnu_ilp32` | ✓ | ✓ | ARM64 Linux (ILP32 ABI) @@ -304,7 +304,7 @@ target | std | host | notes `x86_64-apple-ios-macabi` | ✓ | | Apple Catalyst on x86_64 `x86_64-apple-tvos` | * | | x86 64-bit tvOS [`x86_64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ | | x86 64-bit Apple WatchOS simulator -[`x86_64-pc-nto-qnx7.1.0`](platform-support/nto-qnx.md) | ? | | x86 64-bit QNX Neutrino 7.1 RTOS | +[`x86_64-pc-nto-qnx710`](platform-support/nto-qnx.md) | ? | | x86 64-bit QNX Neutrino 7.1 RTOS | [`x86_64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ | `x86_64-pc-windows-msvc` | * | | 64-bit Windows XP support `x86_64-sun-solaris` | ? | | Deprecated target for 64-bit Solaris 10/11, illumos diff --git a/src/doc/rustc/src/platform-support/nto-qnx.md b/src/doc/rustc/src/platform-support/nto-qnx.md index 2f6ea94d113a9..37d0c31976c77 100644 --- a/src/doc/rustc/src/platform-support/nto-qnx.md +++ b/src/doc/rustc/src/platform-support/nto-qnx.md @@ -93,15 +93,15 @@ Run the following: ```bash env \ - CC_aarch64-unknown-nto-qnx7.1.0="qcc" \ - CFLAGS_aarch64-unknown-nto-qnx7.1.0="-Vgcc_ntoaarch64le_cxx" \ - CXX_aarch64-unknown-nto-qnx7.1.0="qcc" \ - AR_aarch64_unknown_nto_qnx7.1.0="ntoaarch64-ar" \ - CC_x86_64-pc-nto-qnx7.1.0="qcc" \ - CFLAGS_x86_64-pc-nto-qnx7.1.0="-Vgcc_ntox86_64_cxx" \ - CXX_x86_64-pc-nto-qnx7.1.0="qcc" \ - AR_x86_64_pc_nto_qnx7.1.0="ntox86_64-ar" \ - ./x.py build --target aarch64-unknown-nto-qnx7.1.0 --target x86_64-pc-nto-qnx7.1.0 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/ + CC_aarch64-unknown-nto-qnx710="qcc" \ + CFLAGS_aarch64-unknown-nto-qnx710="-Vgcc_ntoaarch64le_cxx" \ + CXX_aarch64-unknown-nto-qnx710="qcc" \ + AR_aarch64_unknown_nto_qnx710="ntoaarch64-ar" \ + CC_x86_64-pc-nto-qnx710="qcc" \ + CFLAGS_x86_64-pc-nto-qnx710="-Vgcc_ntox86_64_cxx" \ + CXX_x86_64-pc-nto-qnx710="qcc" \ + AR_x86_64_pc_nto_qnx710="ntox86_64-ar" \ + ./x.py build --target aarch64-unknown-nto-qnx710 --target x86_64-pc-nto-qnx710 --target x86_64-unknown-linux-gnu rustc library/core library/alloc/ ``` ## Building Rust programs From 102a5d867c9b82df79ff7465eb8287b700af3bce Mon Sep 17 00:00:00 2001 From: Caleb Zulawski Date: Sat, 19 Nov 2022 21:22:17 -0500 Subject: [PATCH 03/19] Print all features with --print target-features, including aliases and tied features --- compiler/rustc_codegen_llvm/src/llvm_util.rs | 35 +++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs index 4af1aaec0a112..8383a9c853556 100644 --- a/compiler/rustc_codegen_llvm/src/llvm_util.rs +++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs @@ -292,30 +292,33 @@ fn llvm_target_features(tm: &llvm::TargetMachine) -> Vec<(&str, &str)> { } fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) { - let mut target_features = llvm_target_features(tm); + let mut llvm_target_features = llvm_target_features(tm); + let mut known_llvm_target_features = FxHashSet::<&'static str>::default(); let mut rustc_target_features = supported_target_features(sess) .iter() - .filter_map(|(feature, _gate)| { - for llvm_feature in to_llvm_features(sess, *feature) { + .map(|(feature, _gate)| { + let desc = if let Some(llvm_feature) = to_llvm_features(sess, *feature).first() { // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings. - match target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok().map( - |index| { - let (_f, desc) = target_features.remove(index); - (*feature, desc) - }, - ) { - Some(v) => return Some(v), - None => {} + match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() { + Some(index) => { + known_llvm_target_features.insert(llvm_feature); + llvm_target_features[index].1 + } + None => "", } - } - None + } else { + "" + }; + (*feature, desc) }) .collect::>(); rustc_target_features.extend_from_slice(&[( "crt-static", "Enables C Run-time Libraries to be statically linked", )]); - let max_feature_len = target_features + llvm_target_features.retain(|(f, _d)| !known_llvm_target_features.contains(f)); + + let max_feature_len = llvm_target_features .iter() .chain(rustc_target_features.iter()) .map(|(feature, _desc)| feature.len()) @@ -327,10 +330,10 @@ fn print_target_features(sess: &Session, tm: &llvm::TargetMachine) { println!(" {1:0$} - {2}.", max_feature_len, feature, desc); } println!("\nCode-generation features supported by LLVM for this target:"); - for (feature, desc) in &target_features { + for (feature, desc) in &llvm_target_features { println!(" {1:0$} - {2}.", max_feature_len, feature, desc); } - if target_features.is_empty() { + if llvm_target_features.is_empty() { println!(" Target features listing is not supported by this LLVM version."); } println!("\nUse +feature to enable a feature, or -feature to disable it."); From 005c6dfde667654c48ec2dd873bd3e9d0a5ae66b Mon Sep 17 00:00:00 2001 From: ismailmaj Date: Mon, 21 Nov 2022 10:38:04 +0100 Subject: [PATCH 04/19] type annotate &str when stack allocating a string --- library/core/src/str/converts.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/core/src/str/converts.rs b/library/core/src/str/converts.rs index b0c55ca4f5139..5f8748206d764 100644 --- a/library/core/src/str/converts.rs +++ b/library/core/src/str/converts.rs @@ -77,7 +77,7 @@ use super::Utf8Error; /// let sparkle_heart = [240, 159, 146, 150]; /// /// // We know these bytes are valid, so just use `unwrap()`. -/// let sparkle_heart = str::from_utf8(&sparkle_heart).unwrap(); +/// let sparkle_heart: &str = str::from_utf8(&sparkle_heart).unwrap(); /// /// assert_eq!("💖", sparkle_heart); /// ``` From ca57832db636fedeeb529a1cc1feab0befef2ab0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 21 Nov 2022 20:16:36 +0000 Subject: [PATCH 05/19] Add more regression tests --- .../rustc_borrowck/src/region_infer/mod.rs | 12 +++--- .../imply_bounds_from_bounds.rs | 25 ++++++++++++ .../imply_bounds_from_bounds_param.rs | 38 +++++++++++++++++++ .../imply_bounds_from_bounds_param.stderr | 16 ++++++++ .../type-alias-impl-trait/self_implication.rs | 38 +++++++++++++++++++ 5 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs create mode 100644 src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs create mode 100644 src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr create mode 100644 src/test/ui/type-alias-impl-trait/self_implication.rs diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index b35abbd107b9c..90e2b6b698cf8 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -1705,6 +1705,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { }); } + #[instrument(level = "debug", skip(self, infcx, errors_buffer))] fn check_member_constraints( &self, infcx: &InferCtxt<'tcx>, @@ -1712,22 +1713,21 @@ impl<'tcx> RegionInferenceContext<'tcx> { ) { let member_constraints = self.member_constraints.clone(); for m_c_i in member_constraints.all_indices() { - debug!("check_member_constraint(m_c_i={:?})", m_c_i); + debug!(?m_c_i); let m_c = &member_constraints[m_c_i]; let member_region_vid = m_c.member_region_vid; debug!( - "check_member_constraint: member_region_vid={:?} with value {}", - member_region_vid, - self.region_value_str(member_region_vid), + ?member_region_vid, + value = ?self.region_value_str(member_region_vid), ); let choice_regions = member_constraints.choice_regions(m_c_i); - debug!("check_member_constraint: choice_regions={:?}", choice_regions); + debug!(?choice_regions); // Did the member region wind up equal to any of the option regions? if let Some(o) = choice_regions.iter().find(|&&o_r| self.eval_equal(o_r, m_c.member_region_vid)) { - debug!("check_member_constraint: evaluated as equal to {:?}", o); + debug!("evaluated as equal to {:?}", o); continue; } diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs new file mode 100644 index 0000000000000..ee9bce15d3478 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds.rs @@ -0,0 +1,25 @@ +// check-pass + +#![feature(type_alias_impl_trait)] + +trait Callable { + type Output; + fn call() -> Self::Output; +} + +impl<'a> Callable for &'a () { + type Output = impl Sized; + fn call() -> Self::Output {} +} + +fn test<'a>() -> impl Sized { + <&'a () as Callable>::call() +} + +fn want_static(_: T) {} + +fn test2<'a>() { + want_static(<&'a () as Callable>::call()); +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs new file mode 100644 index 0000000000000..ae21a9134a416 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.rs @@ -0,0 +1,38 @@ +#![feature(type_alias_impl_trait)] + +trait Callable { + type Output; + fn call(x: Self) -> Self::Output; +} + +trait PlusOne { + fn plus_one(&mut self); +} + +impl<'a> PlusOne for &'a mut i32 { + fn plus_one(&mut self) { + **self += 1; + } +} + +impl Callable for T { + type Output = impl PlusOne; + fn call(t: T) -> Self::Output { t } +} + +fn test<'a>(y: &'a mut i32) -> impl PlusOne { + <&'a mut i32 as Callable>::call(y) + //~^ ERROR hidden type for `impl PlusOne` captures lifetime that does not appear in bounds +} + +fn main() { + let mut z = 42; + let mut thing = test(&mut z); + let mut thing2 = test(&mut z); + thing.plus_one(); + assert_eq!(z, 43); + thing2.plus_one(); + assert_eq!(z, 44); + thing.plus_one(); + assert_eq!(z, 45); +} diff --git a/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr new file mode 100644 index 0000000000000..0ed8a703b6dc5 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/imply_bounds_from_bounds_param.stderr @@ -0,0 +1,16 @@ +error[E0700]: hidden type for `impl PlusOne` captures lifetime that does not appear in bounds + --> $DIR/imply_bounds_from_bounds_param.rs:24:5 + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne { + | -- hidden type `<&'a mut i32 as Callable>::Output` captures the lifetime `'a` as defined here +LL | <&'a mut i32 as Callable>::call(y) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl PlusOne` captures `'a`, you can add an explicit `'a` lifetime bound + | +LL | fn test<'a>(y: &'a mut i32) -> impl PlusOne + 'a { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0700`. diff --git a/src/test/ui/type-alias-impl-trait/self_implication.rs b/src/test/ui/type-alias-impl-trait/self_implication.rs new file mode 100644 index 0000000000000..4e805ee308f4d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/self_implication.rs @@ -0,0 +1,38 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +fn foo() { + struct Foo<'a> { + x: &'a mut u8, + } + impl<'a> Foo<'a> { + fn foo(&self) -> impl Sized {} + } + // use site + let mut x = 5; + let y = Foo { x: &mut x }; + let z = y.foo(); + let _a = &x; // invalidate the `&'a mut`in `y` + let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live +} + +fn bar() { + struct Foo<'a> { + x: &'a mut u8, + } + + // desugared + type FooX<'a> = impl Sized; + impl<'a> Foo<'a> { + fn foo(&self) -> FooX<'a> {} + } + + // use site + let mut x = 5; + let y = Foo { x: &mut x }; + let z = y.foo(); + let _a = &x; // invalidate the `&'a mut`in `y` + let _b = z; // this should *not* check that `'a` in the type `Foo<'a>::foo::opaque` is live +} + +fn main() {} From 9d66ab0f9dea6d8203ceeb29e7da0fd48945ddb7 Mon Sep 17 00:00:00 2001 From: Andres Suarez Date: Mon, 28 Nov 2022 02:40:38 +0000 Subject: [PATCH 06/19] Add `as_mut_os_string` to `&mut PathBuf` and `as_mut_os_str` to `&mut Path` Implements rust-lang/libs-team#140 --- library/std/src/path.rs | 46 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/library/std/src/path.rs b/library/std/src/path.rs index af88b9070c189..6c957c2fa90eb 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -1463,6 +1463,30 @@ impl PathBuf { true } + /// Yields a mutable reference to the underlying [`OsString`] instance. + /// + /// # Examples + /// + /// ``` + /// #![feature(path_as_mut_os_str)] + /// use std::path::{Path, PathBuf}; + /// + /// let mut path = PathBuf::from("/foo"); + /// + /// path.push("bar"); + /// assert_eq!(path, Path::new("/foo/bar")); + /// + /// // OsString's `push` does not add a separator. + /// path.as_mut_os_string().push("baz"); + /// assert_eq!(path, Path::new("/foo/barbaz")); + /// ``` + #[unstable(feature = "path_as_mut_os_str", issue = "105021")] + #[must_use] + #[inline] + pub fn as_mut_os_string(&mut self) -> &mut OsString { + &mut self.inner + } + /// Consumes the `PathBuf`, yielding its internal [`OsString`] storage. /// /// # Examples @@ -1993,6 +2017,28 @@ impl Path { &self.inner } + /// Yields a mutable reference to the underlying [`OsStr`] slice. + /// + /// # Examples + /// + /// ``` + /// #![feature(path_as_mut_os_str)] + /// use std::path::{Path, PathBuf}; + /// + /// let mut path = PathBuf::from("/Foo.TXT").into_boxed_path(); + /// + /// assert_ne!(&*path, Path::new("/foo.txt")); + /// + /// path.as_mut_os_str().make_ascii_lowercase(); + /// assert_eq!(&*path, Path::new("/foo.txt")); + /// ``` + #[unstable(feature = "path_as_mut_os_str", issue = "105021")] + #[must_use] + #[inline] + pub fn as_mut_os_str(&mut self) -> &mut OsStr { + &mut self.inner + } + /// Yields a [`&str`] slice if the `Path` is valid unicode. /// /// This conversion may entail doing a check for UTF-8 validity. From 63915be212d0c054c764b7dd5c408e2c10af219c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Mon, 28 Nov 2022 00:00:00 +0000 Subject: [PATCH 07/19] Statics used in reachable function's inline asm are reachable --- compiler/rustc_passes/src/reachable.rs | 11 ++++++++++ .../codegen-units/item-collection/asm-sym.rs | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/test/codegen-units/item-collection/asm-sym.rs diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index 73ea06a6370d4..e7c3c712852dd 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -116,6 +116,17 @@ impl<'tcx> Visitor<'tcx> for ReachableContext<'tcx> { intravisit::walk_expr(self, expr) } + + fn visit_inline_asm(&mut self, asm: &'tcx hir::InlineAsm<'tcx>, id: hir::HirId) { + for (op, _) in asm.operands { + if let hir::InlineAsmOperand::SymStatic { def_id, .. } = op { + if let Some(def_id) = def_id.as_local() { + self.reachable_symbols.insert(def_id); + } + } + } + intravisit::walk_inline_asm(self, asm, id); + } } impl<'tcx> ReachableContext<'tcx> { diff --git a/src/test/codegen-units/item-collection/asm-sym.rs b/src/test/codegen-units/item-collection/asm-sym.rs new file mode 100644 index 0000000000000..8bafb95bc16d9 --- /dev/null +++ b/src/test/codegen-units/item-collection/asm-sym.rs @@ -0,0 +1,20 @@ +// needs-asm-support +// compile-flags: -Ccodegen-units=1 -Zprint-mono-items=lazy --crate-type=lib + +#[inline(always)] +pub unsafe fn f() { + //~ MONO_ITEM static f::S @@ asm_sym-cgu.0[External] + static S: usize = 1; + //~ MONO_ITEM fn f::fun @@ asm_sym-cgu.0[External] + fn fun() {} + core::arch::asm!("/* {0} {1} */", sym S, sym fun); +} + +//~ MONO_ITEM fn g @@ asm_sym-cgu.0[External] +pub unsafe fn g() { + //~ MONO_ITEM static g::S @@ asm_sym-cgu.0[Internal] + static S: usize = 2; + //~ MONO_ITEM fn g::fun @@ asm_sym-cgu.0[Internal] + fn fun() {} + core::arch::asm!("/* {0} {1} */", sym S, sym fun); +} From 07b86a94c77483127a7b7371cb046e67d8e59279 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Mon, 28 Nov 2022 19:16:44 +0000 Subject: [PATCH 08/19] `rustc_ast_passes`: remove `ref` patterns --- .../rustc_ast_passes/src/ast_validation.rs | 95 +++++++++---------- compiler/rustc_ast_passes/src/feature_gate.rs | 20 ++-- 2 files changed, 55 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index acd7eb69ffc37..e47c434454602 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -209,7 +209,7 @@ impl<'a> AstValidator<'a> { // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { - match t.kind { + match &t.kind { TyKind::ImplTrait(..) => { self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t)) } @@ -217,7 +217,7 @@ impl<'a> AstValidator<'a> { .with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| { visit::walk_ty(this, t) }), - TyKind::Path(ref qself, ref path) => { + TyKind::Path(qself, path) => { // We allow these: // - `Option` // - `option::Option` @@ -231,7 +231,7 @@ impl<'a> AstValidator<'a> { // (for cases like `::Foo>`) // but we allow `impl Trait` in `GenericArgs` // iff there are no more PathSegments. - if let Some(ref qself) = *qself { + if let Some(qself) = qself { // `impl Trait` in `qself` is always illegal self.with_banned_impl_trait(|this| this.visit_ty(&qself.ty)); } @@ -738,8 +738,8 @@ impl<'a> AstValidator<'a> { } fn visit_ty_common(&mut self, ty: &'a Ty) { - match ty.kind { - TyKind::BareFn(ref bfty) => { + match &ty.kind { + TyKind::BareFn(bfty) => { self.check_fn_decl(&bfty.decl, SelfSemantic::No); Self::check_decl_no_pat(&bfty.decl, |span, _, _| { struct_span_err!( @@ -756,10 +756,10 @@ impl<'a> AstValidator<'a> { self.maybe_lint_missing_abi(sig_span, ty.id); } } - TyKind::TraitObject(ref bounds, ..) => { + TyKind::TraitObject(bounds, ..) => { let mut any_lifetime_bounds = false; for bound in bounds { - if let GenericBound::Outlives(ref lifetime) = *bound { + if let GenericBound::Outlives(lifetime) = bound { if any_lifetime_bounds { struct_span_err!( self.session, @@ -774,7 +774,7 @@ impl<'a> AstValidator<'a> { } } } - TyKind::ImplTrait(_, ref bounds) => { + TyKind::ImplTrait(_, bounds) => { if self.is_impl_trait_banned { struct_span_err!( self.session, @@ -842,8 +842,8 @@ fn validate_generic_param_order( let (kind, bounds, span) = (¶m.kind, ¶m.bounds, ident.span); let (ord_kind, ident) = match ¶m.kind { GenericParamKind::Lifetime => (ParamKindOrd::Lifetime, ident.to_string()), - GenericParamKind::Type { default: _ } => (ParamKindOrd::TypeOrConst, ident.to_string()), - GenericParamKind::Const { ref ty, kw_span: _, default: _ } => { + GenericParamKind::Type { .. } => (ParamKindOrd::TypeOrConst, ident.to_string()), + GenericParamKind::Const { ty, .. } => { let ty = pprust::ty_to_string(ty); (ParamKindOrd::TypeOrConst, format!("const {}: {}", ident, ty)) } @@ -948,8 +948,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } ExprKind::Paren(local_expr) => { fn has_let_expr(expr: &Expr) -> bool { - match expr.kind { - ExprKind::Binary(_, ref lhs, ref rhs) => has_let_expr(lhs) || has_let_expr(rhs), + match &expr.kind { + ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs), ExprKind::Let(..) => true, _ => false, } @@ -1005,18 +1005,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_nomangle_item_asciionly(item.ident, item.span); } - match item.kind { + match &item.kind { ItemKind::Impl(box Impl { unsafety, polarity, defaultness: _, constness, - ref generics, - of_trait: Some(ref t), - ref self_ty, - ref items, + generics, + of_trait: Some(t), + self_ty, + items, }) => { - self.with_in_trait_impl(true, Some(constness), |this| { + self.with_in_trait_impl(true, Some(*constness), |this| { this.invalid_visibility(&item.vis, None); if let TyKind::Err = self_ty.kind { this.err_handler() @@ -1027,7 +1027,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .help("use `auto trait Trait {}` instead") .emit(); } - if let (Unsafe::Yes(span), ImplPolarity::Negative(sp)) = (unsafety, polarity) { + if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity) + { struct_span_err!( this.session, sp.to(t.path.span), @@ -1061,7 +1062,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { constness, generics: _, of_trait: None, - ref self_ty, + self_ty, items: _, }) => { let error = |annotation_span, annotation| { @@ -1078,25 +1079,25 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, Some(InvalidVisibilityNote::IndividualImplItems), ); - if let Unsafe::Yes(span) = unsafety { + if let &Unsafe::Yes(span) = unsafety { error(span, "unsafe").code(error_code!(E0197)).emit(); } - if let ImplPolarity::Negative(span) = polarity { + if let &ImplPolarity::Negative(span) = polarity { error(span, "negative").emit(); } - if let Defaultness::Default(def_span) = defaultness { + if let &Defaultness::Default(def_span) = defaultness { error(def_span, "`default`") .note("only trait implementations may be annotated with `default`") .emit(); } - if let Const::Yes(span) = constness { + if let &Const::Yes(span) = constness { error(span, "`const`") .note("only trait implementations may be annotated with `const`") .emit(); } } - ItemKind::Fn(box Fn { defaultness, ref sig, ref generics, ref body }) => { - self.check_defaultness(item.span, defaultness); + ItemKind::Fn(box Fn { defaultness, sig, generics, body }) => { + self.check_defaultness(item.span, *defaultness); if body.is_none() { self.session.emit_err(FnWithoutBody { @@ -1132,7 +1133,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, Some(InvalidVisibilityNote::IndividualForeignItems), ); - if let Unsafe::Yes(span) = unsafety { + if let &Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "extern block cannot be declared unsafe"); } if abi.is_none() { @@ -1142,7 +1143,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.extern_mod = old_item; return; // Avoid visiting again. } - ItemKind::Enum(ref def, _) => { + ItemKind::Enum(def, _) => { for variant in &def.variants { self.invalid_visibility(&variant.vis, None); for field in variant.data.fields() { @@ -1150,8 +1151,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - ItemKind::Trait(box Trait { is_auto, ref generics, ref bounds, ref items, .. }) => { - if is_auto == IsAuto::Yes { + ItemKind::Trait(box Trait { is_auto, generics, bounds, items, .. }) => { + if *is_auto == IsAuto::Yes { // Auto traits cannot have generics, super traits nor contain items. self.deny_generic_params(generics, item.ident.span); self.deny_super_traits(bounds, item.ident.span); @@ -1171,8 +1172,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again } - ItemKind::Mod(unsafety, ref mod_kind) => { - if let Unsafe::Yes(span) = unsafety { + ItemKind::Mod(unsafety, mod_kind) => { + if let &Unsafe::Yes(span) = unsafety { self.err_handler().span_err(span, "module cannot be declared unsafe"); } // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). @@ -1182,13 +1183,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_mod_file_item_asciionly(item.ident); } } - ItemKind::Union(ref vdata, ..) => { + ItemKind::Union(vdata, ..) => { if vdata.fields().is_empty() { self.err_handler().span_err(item.span, "unions cannot have zero fields"); } } ItemKind::Const(def, .., None) => { - self.check_defaultness(item.span, def); + self.check_defaultness(item.span, *def); self.session.emit_err(ConstWithoutBody { span: item.span, replace_span: self.ending_semi_or_hi(item.span), @@ -1200,14 +1201,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { replace_span: self.ending_semi_or_hi(item.span), }); } - ItemKind::TyAlias(box TyAlias { - defaultness, - where_clauses, - ref bounds, - ref ty, - .. - }) => { - self.check_defaultness(item.span, defaultness); + ItemKind::TyAlias(box TyAlias { defaultness, where_clauses, bounds, ty, .. }) => { + self.check_defaultness(item.span, *defaultness); if ty.is_none() { self.session.emit_err(TyAliasWithoutBody { span: item.span, @@ -1266,8 +1261,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Mirrors `visit::walk_generic_args`, but tracks relevant state. fn visit_generic_args(&mut self, generic_args: &'a GenericArgs) { - match *generic_args { - GenericArgs::AngleBracketed(ref data) => { + match generic_args { + GenericArgs::AngleBracketed(data) => { self.check_generic_args_before_constraints(data); for arg in &data.args { @@ -1283,7 +1278,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - GenericArgs::Parenthesized(ref data) => { + GenericArgs::Parenthesized(data) => { walk_list!(self, visit_ty, &data.inputs); if let FnRetTy::Ty(ty) = &data.output { // `-> Foo` syntax is essentially an associated type binding, @@ -1319,7 +1314,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { validate_generic_param_order(self.err_handler(), &generics.params, generics.span); for predicate in &generics.where_clause.predicates { - if let WherePredicate::EqPredicate(ref predicate) = *predicate { + if let WherePredicate::EqPredicate(predicate) = predicate { deny_equality_constraints(self, predicate, generics); } } @@ -1368,7 +1363,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } fn visit_param_bound(&mut self, bound: &'a GenericBound, ctxt: BoundKind) { - if let GenericBound::Trait(ref poly, modify) = *bound { + if let GenericBound::Trait(poly, modify) = bound { match (ctxt, modify) { (BoundKind::SuperTraits, TraitBoundModifier::Maybe) => { let mut err = self @@ -1573,8 +1568,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { self.check_item_named(item.ident, "const"); } - match item.kind { - AssocItemKind::Type(box TyAlias { ref generics, ref bounds, ref ty, .. }) + match &item.kind { + AssocItemKind::Type(box TyAlias { generics, bounds, ty, .. }) if ctxt == AssocCtxt::Trait => { self.visit_vis(&item.vis); @@ -1586,7 +1581,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { }); walk_list!(self, visit_ty, ty); } - AssocItemKind::Fn(box Fn { ref sig, ref generics, ref body, .. }) + AssocItemKind::Fn(box Fn { sig, generics, body, .. }) if self.in_const_trait_impl || ctxt == AssocCtxt::Trait || matches!(sig.header.constness, Const::Yes(_)) => diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 546010135a725..32f45f8b59e90 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -198,8 +198,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_item(&mut self, i: &'a ast::Item) { - match i.kind { - ast::ItemKind::ForeignMod(ref foreign_module) => { + match &i.kind { + ast::ItemKind::ForeignMod(foreign_module) => { if let Some(abi) = foreign_module.abi { self.check_abi(abi, ast::Const::No); } @@ -233,8 +233,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, ref of_trait, .. }) => { - if let ast::ImplPolarity::Negative(span) = polarity { + ast::ItemKind::Impl(box ast::Impl { polarity, defaultness, of_trait, .. }) => { + if let &ast::ImplPolarity::Negative(span) = polarity { gate_feature_post!( &self, negative_impls, @@ -267,7 +267,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, decl_macro, i.span, msg); } - ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ref ty), .. }) => { + ast::ItemKind::TyAlias(box ast::TyAlias { ty: Some(ty), .. }) => { self.check_impl_trait(&ty) } @@ -302,8 +302,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_ty(&mut self, ty: &'a ast::Ty) { - match ty.kind { - ast::TyKind::BareFn(ref bare_fn_ty) => { + match &ty.kind { + ast::TyKind::BareFn(bare_fn_ty) => { // Function pointers cannot be `const` self.check_extern(bare_fn_ty.ext, ast::Const::No); } @@ -319,7 +319,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) { - if let ast::FnRetTy::Ty(ref output_ty) = *ret_ty { + if let ast::FnRetTy::Ty(output_ty) = ret_ty { if let ast::TyKind::Never = output_ty.kind { // Do nothing. } else { @@ -455,9 +455,9 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } fn visit_assoc_item(&mut self, i: &'a ast::AssocItem, ctxt: AssocCtxt) { - let is_fn = match i.kind { + let is_fn = match &i.kind { ast::AssocItemKind::Fn(_) => true, - ast::AssocItemKind::Type(box ast::TyAlias { ref ty, .. }) => { + ast::AssocItemKind::Type(box ast::TyAlias { ty, .. }) => { if let (Some(_), AssocCtxt::Trait) = (ty, ctxt) { gate_feature_post!( &self, From 56ae9a1746f266097eb51cd958f31c406b6eb233 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 29 Nov 2022 08:08:26 +0000 Subject: [PATCH 09/19] `rustc_ast_pretty`: remove `ref` patterns --- compiler/rustc_ast_pretty/src/pprust/state.rs | 175 +++++++++--------- .../rustc_ast_pretty/src/pprust/state/expr.rs | 144 +++++++------- .../rustc_ast_pretty/src/pprust/state/item.rs | 111 +++++------ 3 files changed, 214 insertions(+), 216 deletions(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 7a9243c511b92..0fe1045c244cb 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -11,7 +11,7 @@ use rustc_ast::tokenstream::{TokenStream, TokenTree}; use rustc_ast::util::classify; use rustc_ast::util::comments::{gather_comments, Comment, CommentStyle}; use rustc_ast::util::parser; -use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, Mutability, PatKind}; +use rustc_ast::{self as ast, AttrArgs, AttrArgsEq, BlockCheckMode, PatKind}; use rustc_ast::{attr, BindingAnnotation, ByRef, DelimArgs, RangeEnd, RangeSyntax, Term}; use rustc_ast::{GenericArg, GenericBound, SelfKind, TraitBoundModifier}; use rustc_ast::{InlineAsmOperand, InlineAsmRegOrRegClass}; @@ -64,6 +64,7 @@ impl<'a> Comments<'a> { Comments { sm, comments, current: 0 } } + // This shouldn't probably clone lmao pub fn next(&self) -> Option { self.comments.get(self.current).cloned() } @@ -268,10 +269,10 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn maybe_print_comment(&mut self, pos: BytePos) -> bool { let mut has_comment = false; - while let Some(ref cmnt) = self.next_comment() { + while let Some(cmnt) = self.next_comment() { if cmnt.pos < pos { has_comment = true; - self.print_comment(cmnt); + self.print_comment(&cmnt); } else { break; } @@ -366,8 +367,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere if self.next_comment().is_none() { self.hardbreak(); } - while let Some(ref cmnt) = self.next_comment() { - self.print_comment(cmnt) + while let Some(cmnt) = self.next_comment() { + self.print_comment(&cmnt) } } @@ -446,8 +447,8 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.hardbreak_if_not_bol(); } self.maybe_print_comment(attr.span.lo()); - match attr.kind { - ast::AttrKind::Normal(ref normal) => { + match &attr.kind { + ast::AttrKind::Normal(normal) => { match attr.style { ast::AttrStyle::Inner => self.word("#!["), ast::AttrStyle::Outer => self.word("#["), @@ -456,7 +457,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere self.word("]"); } ast::AttrKind::DocComment(comment_kind, data) => { - self.word(doc_comment_to_string(comment_kind, attr.style, data)); + self.word(doc_comment_to_string(*comment_kind, attr.style, *data)); self.hardbreak() } } @@ -497,22 +498,22 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_meta_list_item(&mut self, item: &ast::NestedMetaItem) { match item { - ast::NestedMetaItem::MetaItem(ref mi) => self.print_meta_item(mi), - ast::NestedMetaItem::Lit(ref lit) => self.print_meta_item_lit(lit), + ast::NestedMetaItem::MetaItem(mi) => self.print_meta_item(mi), + ast::NestedMetaItem::Lit(lit) => self.print_meta_item_lit(lit), } } fn print_meta_item(&mut self, item: &ast::MetaItem) { self.ibox(INDENT_UNIT); - match item.kind { + match &item.kind { ast::MetaItemKind::Word => self.print_path(&item.path, false, 0), - ast::MetaItemKind::NameValue(ref value) => { + ast::MetaItemKind::NameValue(value) => { self.print_path(&item.path, false, 0); self.space(); self.word_space("="); self.print_meta_item_lit(value); } - ast::MetaItemKind::List(ref items) => { + ast::MetaItemKind::List(items) => { self.print_path(&item.path, false, 0); self.popen(); self.commasep(Consistent, &items, |s, i| s.print_meta_list_item(i)); @@ -657,7 +658,7 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere fn print_path_segment(&mut self, segment: &ast::PathSegment, colons_before_params: bool) { if segment.ident.name != kw::PathRoot { self.print_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { self.print_generic_args(args, colons_before_params); } } @@ -712,19 +713,19 @@ pub trait PrintState<'a>: std::ops::Deref + std::ops::Dere } fn nonterminal_to_string(&self, nt: &Nonterminal) -> String { - match *nt { - token::NtExpr(ref e) => self.expr_to_string(e), - token::NtMeta(ref e) => self.attr_item_to_string(e), - token::NtTy(ref e) => self.ty_to_string(e), - token::NtPath(ref e) => self.path_to_string(e), - token::NtItem(ref e) => self.item_to_string(e), - token::NtBlock(ref e) => self.block_to_string(e), - token::NtStmt(ref e) => self.stmt_to_string(e), - token::NtPat(ref e) => self.pat_to_string(e), - token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(e, is_raw).to_string(), + match nt { + token::NtExpr(e) => self.expr_to_string(e), + token::NtMeta(e) => self.attr_item_to_string(e), + token::NtTy(e) => self.ty_to_string(e), + token::NtPath(e) => self.path_to_string(e), + token::NtItem(e) => self.item_to_string(e), + token::NtBlock(e) => self.block_to_string(e), + token::NtStmt(e) => self.stmt_to_string(e), + token::NtPat(e) => self.pat_to_string(e), + token::NtIdent(e, is_raw) => IdentPrinter::for_ast_ident(*e, *is_raw).to_string(), token::NtLifetime(e) => e.to_string(), - token::NtLiteral(ref e) => self.expr_to_string(e), - token::NtVis(ref e) => self.vis_to_string(e), + token::NtLiteral(e) => self.expr_to_string(e), + token::NtVis(e) => self.vis_to_string(e), } } @@ -917,8 +918,8 @@ impl<'a> PrintState<'a> for State<'a> { self.word("::") } - match *args { - ast::GenericArgs::AngleBracketed(ref data) => { + match args { + ast::GenericArgs::AngleBracketed(data) => { self.word("<"); self.commasep(Inconsistent, &data.args, |s, arg| match arg { ast::AngleBracketedArg::Arg(a) => s.print_generic_arg(a), @@ -927,7 +928,7 @@ impl<'a> PrintState<'a> for State<'a> { self.word(">") } - ast::GenericArgs::Parenthesized(ref data) => { + ast::GenericArgs::Parenthesized(data) => { self.word("("); self.commasep(Inconsistent, &data.inputs, |s, ty| s.print_type(ty)); self.word(")"); @@ -1011,17 +1012,17 @@ impl<'a> State<'a> { pub fn print_type(&mut self, ty: &ast::Ty) { self.maybe_print_comment(ty.span.lo()); self.ibox(0); - match ty.kind { - ast::TyKind::Slice(ref ty) => { + match &ty.kind { + ast::TyKind::Slice(ty) => { self.word("["); self.print_type(ty); self.word("]"); } - ast::TyKind::Ptr(ref mt) => { + ast::TyKind::Ptr(mt) => { self.word("*"); self.print_mt(mt, true); } - ast::TyKind::Rptr(ref lifetime, ref mt) => { + ast::TyKind::Rptr(lifetime, mt) => { self.word("&"); self.print_opt_lifetime(lifetime); self.print_mt(mt, false); @@ -1029,7 +1030,7 @@ impl<'a> State<'a> { ast::TyKind::Never => { self.word("!"); } - ast::TyKind::Tup(ref elts) => { + ast::TyKind::Tup(elts) => { self.popen(); self.commasep(Inconsistent, &elts, |s, ty| s.print_type(ty)); if elts.len() == 1 { @@ -1037,36 +1038,36 @@ impl<'a> State<'a> { } self.pclose(); } - ast::TyKind::Paren(ref typ) => { + ast::TyKind::Paren(typ) => { self.popen(); self.print_type(typ); self.pclose(); } - ast::TyKind::BareFn(ref f) => { + ast::TyKind::BareFn(f) => { self.print_ty_fn(f.ext, f.unsafety, &f.decl, None, &f.generic_params); } - ast::TyKind::Path(None, ref path) => { + ast::TyKind::Path(None, path) => { self.print_path(path, false, 0); } - ast::TyKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, false), - ast::TyKind::TraitObject(ref bounds, syntax) => { - if syntax == ast::TraitObjectSyntax::Dyn { + ast::TyKind::Path(Some(qself), path) => self.print_qpath(path, qself, false), + ast::TyKind::TraitObject(bounds, syntax) => { + if *syntax == ast::TraitObjectSyntax::Dyn { self.word_nbsp("dyn"); } self.print_type_bounds(bounds); } - ast::TyKind::ImplTrait(_, ref bounds) => { + ast::TyKind::ImplTrait(_, bounds) => { self.word_nbsp("impl"); self.print_type_bounds(bounds); } - ast::TyKind::Array(ref ty, ref length) => { + ast::TyKind::Array(ty, length) => { self.word("["); self.print_type(ty); self.word("; "); self.print_expr(&length.value); self.word("]"); } - ast::TyKind::Typeof(ref e) => { + ast::TyKind::Typeof(e) => { self.word("typeof("); self.print_expr(&e.value); self.word(")"); @@ -1082,7 +1083,7 @@ impl<'a> State<'a> { ast::TyKind::ImplicitSelf => { self.word("Self"); } - ast::TyKind::MacCall(ref m) => { + ast::TyKind::MacCall(m) => { self.print_mac(m); } ast::TyKind::CVarArgs => { @@ -1111,8 +1112,8 @@ impl<'a> State<'a> { pub(crate) fn print_stmt(&mut self, st: &ast::Stmt) { self.maybe_print_comment(st.span.lo()); - match st.kind { - ast::StmtKind::Local(ref loc) => { + match &st.kind { + ast::StmtKind::Local(loc) => { self.print_outer_attributes(&loc.attrs); self.space_if_not_bol(); self.ibox(INDENT_UNIT); @@ -1135,15 +1136,15 @@ impl<'a> State<'a> { self.word(";"); self.end(); // `let` ibox } - ast::StmtKind::Item(ref item) => self.print_item(item), - ast::StmtKind::Expr(ref expr) => { + ast::StmtKind::Item(item) => self.print_item(item), + ast::StmtKind::Expr(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); if classify::expr_requires_semi_to_be_stmt(expr) { self.word(";"); } } - ast::StmtKind::Semi(ref expr) => { + ast::StmtKind::Semi(expr) => { self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); self.word(";"); @@ -1152,7 +1153,7 @@ impl<'a> State<'a> { self.space_if_not_bol(); self.word(";"); } - ast::StmtKind::MacCall(ref mac) => { + ast::StmtKind::MacCall(mac) => { self.space_if_not_bol(); self.print_outer_attributes(&mac.attrs); self.print_mac(&mac.mac); @@ -1193,8 +1194,8 @@ impl<'a> State<'a> { let has_attrs = self.print_inner_attributes(attrs); for (i, st) in blk.stmts.iter().enumerate() { - match st.kind { - ast::StmtKind::Expr(ref expr) if i == blk.stmts.len() - 1 => { + match &st.kind { + ast::StmtKind::Expr(expr) if i == blk.stmts.len() - 1 => { self.maybe_print_comment(st.span.lo()); self.space_if_not_bol(); self.print_expr_outer_attr_style(expr, false); @@ -1362,7 +1363,7 @@ impl<'a> State<'a> { pub(crate) fn print_local_decl(&mut self, loc: &ast::Local) { self.print_pat(&loc.pat); - if let Some(ref ty) = loc.ty { + if let Some(ty) = &loc.ty { self.word_space(":"); self.print_type(ty); } @@ -1386,7 +1387,7 @@ impl<'a> State<'a> { for item_segment in &path.segments[qself.position..] { self.word("::"); self.print_ident(item_segment.ident); - if let Some(ref args) = item_segment.args { + if let Some(args) = &item_segment.args { self.print_generic_args(args, colons_before_params) } } @@ -1397,23 +1398,23 @@ impl<'a> State<'a> { self.ann.pre(self, AnnNode::Pat(pat)); /* Pat isn't normalized, but the beauty of it is that it doesn't matter */ - match pat.kind { + match &pat.kind { PatKind::Wild => self.word("_"), - PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, ref sub) => { - if by_ref == ByRef::Yes { + PatKind::Ident(BindingAnnotation(by_ref, mutbl), ident, sub) => { + if *by_ref == ByRef::Yes { self.word_nbsp("ref"); } - if mutbl == Mutability::Mut { + if mutbl.is_mut() { self.word_nbsp("mut"); } - self.print_ident(ident); - if let Some(ref p) = *sub { + self.print_ident(*ident); + if let Some(p) = sub { self.space(); self.word_space("@"); self.print_pat(p); } } - PatKind::TupleStruct(ref qself, ref path, ref elts) => { + PatKind::TupleStruct(qself, path, elts) => { if let Some(qself) = qself { self.print_qpath(path, qself, true); } else { @@ -1423,16 +1424,16 @@ impl<'a> State<'a> { self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.pclose(); } - PatKind::Or(ref pats) => { + PatKind::Or(pats) => { self.strsep("|", true, Inconsistent, &pats, |s, p| s.print_pat(p)); } - PatKind::Path(None, ref path) => { + PatKind::Path(None, path) => { self.print_path(path, true, 0); } - PatKind::Path(Some(ref qself), ref path) => { + PatKind::Path(Some(qself), path) => { self.print_qpath(path, qself, false); } - PatKind::Struct(ref qself, ref path, ref fields, etc) => { + PatKind::Struct(qself, path, fields, etc) => { if let Some(qself) = qself { self.print_qpath(path, qself, true); } else { @@ -1458,7 +1459,7 @@ impl<'a> State<'a> { }, |f| f.pat.span, ); - if etc { + if *etc { if !fields.is_empty() { self.word_space(","); } @@ -1469,7 +1470,7 @@ impl<'a> State<'a> { } self.word("}"); } - PatKind::Tuple(ref elts) => { + PatKind::Tuple(elts) => { self.popen(); self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); if elts.len() == 1 { @@ -1477,13 +1478,13 @@ impl<'a> State<'a> { } self.pclose(); } - PatKind::Box(ref inner) => { + PatKind::Box(inner) => { self.word("box "); self.print_pat(inner); } - PatKind::Ref(ref inner, mutbl) => { + PatKind::Ref(inner, mutbl) => { self.word("&"); - if mutbl == Mutability::Mut { + if mutbl.is_mut() { self.word("mut "); } if let PatKind::Ident(ast::BindingAnnotation::MUT, ..) = inner.kind { @@ -1494,12 +1495,12 @@ impl<'a> State<'a> { self.print_pat(inner); } } - PatKind::Lit(ref e) => self.print_expr(&**e), - PatKind::Range(ref begin, ref end, Spanned { node: ref end_kind, .. }) => { + PatKind::Lit(e) => self.print_expr(&**e), + PatKind::Range(begin, end, Spanned { node: end_kind, .. }) => { if let Some(e) = begin { self.print_expr(e); } - match *end_kind { + match end_kind { RangeEnd::Included(RangeSyntax::DotDotDot) => self.word("..."), RangeEnd::Included(RangeSyntax::DotDotEq) => self.word("..="), RangeEnd::Excluded => self.word(".."), @@ -1508,36 +1509,36 @@ impl<'a> State<'a> { self.print_expr(e); } } - PatKind::Slice(ref elts) => { + PatKind::Slice(elts) => { self.word("["); self.commasep(Inconsistent, &elts, |s, p| s.print_pat(p)); self.word("]"); } PatKind::Rest => self.word(".."), - PatKind::Paren(ref inner) => { + PatKind::Paren(inner) => { self.popen(); self.print_pat(inner); self.pclose(); } - PatKind::MacCall(ref m) => self.print_mac(m), + PatKind::MacCall(m) => self.print_mac(m), } self.ann.post(self, AnnNode::Pat(pat)) } fn print_explicit_self(&mut self, explicit_self: &ast::ExplicitSelf) { - match explicit_self.node { + match &explicit_self.node { SelfKind::Value(m) => { - self.print_mutability(m, false); + self.print_mutability(*m, false); self.word("self") } - SelfKind::Region(ref lt, m) => { + SelfKind::Region(lt, m) => { self.word("&"); self.print_opt_lifetime(lt); - self.print_mutability(m, false); + self.print_mutability(*m, false); self.word("self") } - SelfKind::Explicit(ref typ, m) => { - self.print_mutability(m, false); + SelfKind::Explicit(typ, m) => { + self.print_mutability(*m, false); self.word("self"); self.word_space(":"); self.print_type(typ) @@ -1599,7 +1600,7 @@ impl<'a> State<'a> { self.commasep(Inconsistent, &generic_params, |s, param| { s.print_outer_attributes_inline(¶m.attrs); - match param.kind { + match ¶m.kind { ast::GenericParamKind::Lifetime => { let lt = ast::Lifetime { id: param.id, ident: param.ident }; s.print_lifetime(lt); @@ -1608,19 +1609,19 @@ impl<'a> State<'a> { s.print_lifetime_bounds(¶m.bounds) } } - ast::GenericParamKind::Type { ref default } => { + ast::GenericParamKind::Type { default } => { s.print_ident(param.ident); if !param.bounds.is_empty() { s.word_nbsp(":"); s.print_type_bounds(¶m.bounds); } - if let Some(ref default) = default { + if let Some(default) = default { s.space(); s.word_space("="); s.print_type(default) } } - ast::GenericParamKind::Const { ref ty, kw_span: _, ref default } => { + ast::GenericParamKind::Const { ty, default, .. } => { s.word_space("const"); s.print_ident(param.ident); s.space(); @@ -1630,7 +1631,7 @@ impl<'a> State<'a> { s.word_nbsp(":"); s.print_type_bounds(¶m.bounds); } - if let Some(ref default) = default { + if let Some(default) = default { s.space(); s.word_space("="); s.print_expr(&default.value); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs index f4d77549eff4c..81483ac30d1de 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs @@ -8,9 +8,9 @@ use rustc_ast::{self as ast, BlockCheckMode}; impl<'a> State<'a> { fn print_else(&mut self, els: Option<&ast::Expr>) { if let Some(_else) = els { - match _else.kind { + match &_else.kind { // Another `else if` block. - ast::ExprKind::If(ref i, ref then, ref e) => { + ast::ExprKind::If(i, then, e) => { self.cbox(INDENT_UNIT - 1); self.ibox(0); self.word(" else if "); @@ -20,7 +20,7 @@ impl<'a> State<'a> { self.print_else(e.as_deref()) } // Final `else` block. - ast::ExprKind::Block(ref b, _) => { + ast::ExprKind::Block(b, _) => { self.cbox(INDENT_UNIT - 1); self.ibox(0); self.word(" else "); @@ -202,7 +202,7 @@ impl<'a> State<'a> { self.print_expr_maybe_paren(receiver, parser::PREC_POSTFIX); self.word("."); self.print_ident(segment.ident); - if let Some(ref args) = segment.args { + if let Some(args) = &segment.args { self.print_generic_args(args, true); } self.print_call_post(base_args) @@ -284,73 +284,66 @@ impl<'a> State<'a> { self.ibox(INDENT_UNIT); self.ann.pre(self, AnnNode::Expr(expr)); - match expr.kind { - ast::ExprKind::Box(ref expr) => { + match &expr.kind { + ast::ExprKind::Box(expr) => { self.word_space("box"); self.print_expr_maybe_paren(expr, parser::PREC_PREFIX); } - ast::ExprKind::Array(ref exprs) => { + ast::ExprKind::Array(exprs) => { self.print_expr_vec(exprs); } - ast::ExprKind::ConstBlock(ref anon_const) => { + ast::ExprKind::ConstBlock(anon_const) => { self.print_expr_anon_const(anon_const, attrs); } - ast::ExprKind::Repeat(ref element, ref count) => { + ast::ExprKind::Repeat(element, count) => { self.print_expr_repeat(element, count); } - ast::ExprKind::Struct(ref se) => { + ast::ExprKind::Struct(se) => { self.print_expr_struct(&se.qself, &se.path, &se.fields, &se.rest); } - ast::ExprKind::Tup(ref exprs) => { + ast::ExprKind::Tup(exprs) => { self.print_expr_tup(exprs); } - ast::ExprKind::Call(ref func, ref args) => { + ast::ExprKind::Call(func, args) => { self.print_expr_call(func, &args); } - ast::ExprKind::MethodCall(box ast::MethodCall { - ref seg, - ref receiver, - ref args, - .. - }) => { + ast::ExprKind::MethodCall(box ast::MethodCall { seg, receiver, args, .. }) => { self.print_expr_method_call(seg, &receiver, &args); } - ast::ExprKind::Binary(op, ref lhs, ref rhs) => { - self.print_expr_binary(op, lhs, rhs); + ast::ExprKind::Binary(op, lhs, rhs) => { + self.print_expr_binary(*op, lhs, rhs); } - ast::ExprKind::Unary(op, ref expr) => { - self.print_expr_unary(op, expr); + ast::ExprKind::Unary(op, expr) => { + self.print_expr_unary(*op, expr); } - ast::ExprKind::AddrOf(k, m, ref expr) => { - self.print_expr_addr_of(k, m, expr); + ast::ExprKind::AddrOf(k, m, expr) => { + self.print_expr_addr_of(*k, *m, expr); } ast::ExprKind::Lit(token_lit) => { - self.print_token_literal(token_lit, expr.span); + self.print_token_literal(*token_lit, expr.span); } - ast::ExprKind::IncludedBytes(ref bytes) => { + ast::ExprKind::IncludedBytes(bytes) => { let lit = ast::LitKind::ByteStr(bytes.clone()).to_token_lit(); self.print_token_literal(lit, expr.span) } - ast::ExprKind::Cast(ref expr, ref ty) => { + ast::ExprKind::Cast(expr, ty) => { let prec = AssocOp::As.precedence() as i8; self.print_expr_maybe_paren(expr, prec); self.space(); self.word_space("as"); self.print_type(ty); } - ast::ExprKind::Type(ref expr, ref ty) => { + ast::ExprKind::Type(expr, ty) => { let prec = AssocOp::Colon.precedence() as i8; self.print_expr_maybe_paren(expr, prec); self.word_space(":"); self.print_type(ty); } - ast::ExprKind::Let(ref pat, ref scrutinee, _) => { + ast::ExprKind::Let(pat, scrutinee, _) => { self.print_let(pat, scrutinee); } - ast::ExprKind::If(ref test, ref blk, ref elseopt) => { - self.print_if(test, blk, elseopt.as_deref()) - } - ast::ExprKind::While(ref test, ref blk, opt_label) => { + ast::ExprKind::If(test, blk, elseopt) => self.print_if(test, blk, elseopt.as_deref()), + ast::ExprKind::While(test, blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -362,7 +355,7 @@ impl<'a> State<'a> { self.space(); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::ForLoop(ref pat, ref iter, ref blk, opt_label) => { + ast::ExprKind::ForLoop(pat, iter, blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -377,7 +370,7 @@ impl<'a> State<'a> { self.space(); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Loop(ref blk, opt_label, _) => { + ast::ExprKind::Loop(blk, opt_label, _) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -387,7 +380,7 @@ impl<'a> State<'a> { self.word_nbsp("loop"); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Match(ref expr, ref arms) => { + ast::ExprKind::Match(expr, arms) => { self.cbox(0); self.ibox(0); self.word_nbsp("match"); @@ -402,18 +395,18 @@ impl<'a> State<'a> { self.bclose(expr.span, empty); } ast::ExprKind::Closure(box ast::Closure { - ref binder, + binder, capture_clause, asyncness, movability, - ref fn_decl, - ref body, + fn_decl, + body, fn_decl_span: _, }) => { self.print_closure_binder(binder); - self.print_movability(movability); - self.print_asyncness(asyncness); - self.print_capture_clause(capture_clause); + self.print_movability(*movability); + self.print_asyncness(*asyncness); + self.print_capture_clause(*capture_clause); self.print_fn_params_and_ret(fn_decl, true); self.space(); @@ -425,7 +418,7 @@ impl<'a> State<'a> { // empty box to satisfy the close. self.ibox(0); } - ast::ExprKind::Block(ref blk, opt_label) => { + ast::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); @@ -436,26 +429,26 @@ impl<'a> State<'a> { self.ibox(0); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Async(capture_clause, _, ref blk) => { + ast::ExprKind::Async(capture_clause, _, blk) => { self.word_nbsp("async"); - self.print_capture_clause(capture_clause); + self.print_capture_clause(*capture_clause); // cbox/ibox in analogy to the `ExprKind::Block` arm above self.cbox(0); self.ibox(0); self.print_block_with_attrs(blk, attrs); } - ast::ExprKind::Await(ref expr) => { + ast::ExprKind::Await(expr) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word(".await"); } - ast::ExprKind::Assign(ref lhs, ref rhs, _) => { + ast::ExprKind::Assign(lhs, rhs, _) => { let prec = AssocOp::Assign.precedence() as i8; self.print_expr_maybe_paren(lhs, prec + 1); self.space(); self.word_space("="); self.print_expr_maybe_paren(rhs, prec); } - ast::ExprKind::AssignOp(op, ref lhs, ref rhs) => { + ast::ExprKind::AssignOp(op, lhs, rhs) => { let prec = AssocOp::Assign.precedence() as i8; self.print_expr_maybe_paren(lhs, prec + 1); self.space(); @@ -463,45 +456,44 @@ impl<'a> State<'a> { self.word_space("="); self.print_expr_maybe_paren(rhs, prec); } - ast::ExprKind::Field(ref expr, ident) => { + ast::ExprKind::Field(expr, ident) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word("."); - self.print_ident(ident); + self.print_ident(*ident); } - ast::ExprKind::Index(ref expr, ref index) => { + ast::ExprKind::Index(expr, index) => { self.print_expr_maybe_paren(expr, parser::PREC_POSTFIX); self.word("["); self.print_expr(index); self.word("]"); } - ast::ExprKind::Range(ref start, ref end, limits) => { + ast::ExprKind::Range(start, end, limits) => { // Special case for `Range`. `AssocOp` claims that `Range` has higher precedence // than `Assign`, but `x .. x = x` gives a parse error instead of `x .. (x = x)`. // Here we use a fake precedence value so that any child with lower precedence than // a "normal" binop gets parenthesized. (`LOr` is the lowest-precedence binop.) let fake_prec = AssocOp::LOr.precedence() as i8; - if let Some(ref e) = *start { + if let Some(e) = start { self.print_expr_maybe_paren(e, fake_prec); } - if limits == ast::RangeLimits::HalfOpen { - self.word(".."); - } else { - self.word("..="); + match limits { + ast::RangeLimits::HalfOpen => self.word(".."), + ast::RangeLimits::Closed => self.word("..="), } - if let Some(ref e) = *end { + if let Some(e) = end { self.print_expr_maybe_paren(e, fake_prec); } } ast::ExprKind::Underscore => self.word("_"), - ast::ExprKind::Path(None, ref path) => self.print_path(path, true, 0), - ast::ExprKind::Path(Some(ref qself), ref path) => self.print_qpath(path, qself, true), - ast::ExprKind::Break(opt_label, ref opt_expr) => { + ast::ExprKind::Path(None, path) => self.print_path(path, true, 0), + ast::ExprKind::Path(Some(qself), path) => self.print_qpath(path, qself, true), + ast::ExprKind::Break(opt_label, opt_expr) => { self.word("break"); if let Some(label) = opt_label { self.space(); self.print_ident(label.ident); } - if let Some(ref expr) = *opt_expr { + if let Some(expr) = opt_expr { self.space(); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } @@ -513,45 +505,45 @@ impl<'a> State<'a> { self.print_ident(label.ident); } } - ast::ExprKind::Ret(ref result) => { + ast::ExprKind::Ret(result) => { self.word("return"); - if let Some(ref expr) = *result { + if let Some(expr) = result { self.word(" "); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::Yeet(ref result) => { + ast::ExprKind::Yeet(result) => { self.word("do"); self.word(" "); self.word("yeet"); - if let Some(ref expr) = *result { + if let Some(expr) = result { self.word(" "); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::InlineAsm(ref a) => { + ast::ExprKind::InlineAsm(a) => { self.word("asm!"); self.print_inline_asm(a); } - ast::ExprKind::MacCall(ref m) => self.print_mac(m), - ast::ExprKind::Paren(ref e) => { + ast::ExprKind::MacCall(m) => self.print_mac(m), + ast::ExprKind::Paren(e) => { self.popen(); self.print_expr(e); self.pclose(); } - ast::ExprKind::Yield(ref e) => { + ast::ExprKind::Yield(e) => { self.word("yield"); - if let Some(ref expr) = *e { + if let Some(expr) = e { self.space(); self.print_expr_maybe_paren(expr, parser::PREC_JUMP); } } - ast::ExprKind::Try(ref e) => { + ast::ExprKind::Try(e) => { self.print_expr_maybe_paren(e, parser::PREC_POSTFIX); self.word("?") } - ast::ExprKind::TryBlock(ref blk) => { + ast::ExprKind::TryBlock(blk) => { self.cbox(0); self.ibox(0); self.word_nbsp("try"); @@ -578,15 +570,15 @@ impl<'a> State<'a> { self.print_outer_attributes(&arm.attrs); self.print_pat(&arm.pat); self.space(); - if let Some(ref e) = arm.guard { + if let Some(e) = &arm.guard { self.word_space("if"); self.print_expr(e); self.space(); } self.word_space("=>"); - match arm.body.kind { - ast::ExprKind::Block(ref blk, opt_label) => { + match &arm.body.kind { + ast::ExprKind::Block(blk, opt_label) => { if let Some(label) = opt_label { self.print_ident(label.ident); self.word_space(":"); diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs index 9c4425701e039..c52f15401abe3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs @@ -136,10 +136,10 @@ impl<'a> State<'a> { self.maybe_print_comment(item.span.lo()); self.print_outer_attributes(&item.attrs); self.ann.pre(self, AnnNode::Item(item)); - match item.kind { + match &item.kind { ast::ItemKind::ExternCrate(orig_name) => { self.head(visibility_qualified(&item.vis, "extern crate")); - if let Some(orig_name) = orig_name { + if let &Some(orig_name) = orig_name { self.print_name(orig_name); self.space(); self.word("as"); @@ -150,35 +150,41 @@ impl<'a> State<'a> { self.end(); // end inner head-block self.end(); // end outer head-block } - ast::ItemKind::Use(ref tree) => { + ast::ItemKind::Use(tree) => { self.print_visibility(&item.vis); self.word_nbsp("use"); self.print_use_tree(tree); self.word(";"); } - ast::ItemKind::Static(ref ty, mutbl, ref body) => { + ast::ItemKind::Static(ty, mutbl, body) => { let def = ast::Defaultness::Final; - self.print_item_const(item.ident, Some(mutbl), ty, body.as_deref(), &item.vis, def); + self.print_item_const( + item.ident, + Some(*mutbl), + ty, + body.as_deref(), + &item.vis, + def, + ); } - ast::ItemKind::Const(def, ref ty, ref body) => { - self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, def); + ast::ItemKind::Const(def, ty, body) => { + self.print_item_const(item.ident, None, ty, body.as_deref(), &item.vis, *def); } - ast::ItemKind::Fn(box ast::Fn { defaultness, ref sig, ref generics, ref body }) => { - let body = body.as_deref(); + ast::ItemKind::Fn(box ast::Fn { defaultness, sig, generics, body }) => { self.print_fn_full( sig, item.ident, generics, &item.vis, - defaultness, - body, + *defaultness, + body.as_deref(), &item.attrs, ); } - ast::ItemKind::Mod(unsafety, ref mod_kind) => { + ast::ItemKind::Mod(unsafety, mod_kind) => { self.head(Self::to_string(|s| { s.print_visibility(&item.vis); - s.print_unsafety(unsafety); + s.print_unsafety(*unsafety); s.word("mod"); })); self.print_ident(item.ident); @@ -201,7 +207,7 @@ impl<'a> State<'a> { } } } - ast::ItemKind::ForeignMod(ref nmod) => { + ast::ItemKind::ForeignMod(nmod) => { self.head(Self::to_string(|s| { s.print_unsafety(nmod.unsafety); s.word("extern"); @@ -215,7 +221,7 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && nmod.items.is_empty(); self.bclose(item.span, empty); } - ast::ItemKind::GlobalAsm(ref asm) => { + ast::ItemKind::GlobalAsm(asm) => { self.head(visibility_qualified(&item.vis, "global_asm!")); self.print_inline_asm(asm); self.word(";"); @@ -224,32 +230,31 @@ impl<'a> State<'a> { } ast::ItemKind::TyAlias(box ast::TyAlias { defaultness, - ref generics, + generics, where_clauses, where_predicates_split, - ref bounds, - ref ty, + bounds, + ty, }) => { - let ty = ty.as_deref(); self.print_associated_type( item.ident, generics, - where_clauses, - where_predicates_split, + *where_clauses, + *where_predicates_split, bounds, - ty, + ty.as_deref(), &item.vis, - defaultness, + *defaultness, ); } - ast::ItemKind::Enum(ref enum_definition, ref params) => { + ast::ItemKind::Enum(enum_definition, params) => { self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis); } - ast::ItemKind::Struct(ref struct_def, ref generics) => { + ast::ItemKind::Struct(struct_def, generics) => { self.head(visibility_qualified(&item.vis, "struct")); self.print_struct(struct_def, generics, item.ident, item.span, true); } - ast::ItemKind::Union(ref struct_def, ref generics) => { + ast::ItemKind::Union(struct_def, generics) => { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident, item.span, true); } @@ -258,15 +263,15 @@ impl<'a> State<'a> { polarity, defaultness, constness, - ref generics, - ref of_trait, - ref self_ty, - ref items, + generics, + of_trait, + self_ty, + items, }) => { self.head(""); self.print_visibility(&item.vis); - self.print_defaultness(defaultness); - self.print_unsafety(unsafety); + self.print_defaultness(*defaultness); + self.print_unsafety(*unsafety); self.word("impl"); if generics.params.is_empty() { @@ -276,13 +281,13 @@ impl<'a> State<'a> { self.space(); } - self.print_constness(constness); + self.print_constness(*constness); if let ast::ImplPolarity::Negative(_) = polarity { self.word("!"); } - if let Some(ref t) = *of_trait { + if let Some(t) = of_trait { self.print_trait_ref(t); self.space(); self.word_space("for"); @@ -303,21 +308,21 @@ impl<'a> State<'a> { ast::ItemKind::Trait(box ast::Trait { is_auto, unsafety, - ref generics, - ref bounds, - ref items, + generics, + bounds, + items, .. }) => { self.head(""); self.print_visibility(&item.vis); - self.print_unsafety(unsafety); - self.print_is_auto(is_auto); + self.print_unsafety(*unsafety); + self.print_is_auto(*is_auto); self.word_nbsp("trait"); self.print_ident(item.ident); self.print_generic_params(&generics.params); let mut real_bounds = Vec::with_capacity(bounds.len()); for b in bounds.iter() { - if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { + if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b { self.space(); self.word_space("for ?"); self.print_trait_ref(&ptr.trait_ref); @@ -339,14 +344,14 @@ impl<'a> State<'a> { let empty = item.attrs.is_empty() && items.is_empty(); self.bclose(item.span, empty); } - ast::ItemKind::TraitAlias(ref generics, ref bounds) => { + ast::ItemKind::TraitAlias(generics, bounds) => { self.head(visibility_qualified(&item.vis, "trait")); self.print_ident(item.ident); self.print_generic_params(&generics.params); let mut real_bounds = Vec::with_capacity(bounds.len()); // FIXME(durka) this seems to be some quite outdated syntax for b in bounds.iter() { - if let GenericBound::Trait(ref ptr, ast::TraitBoundModifier::Maybe) = *b { + if let GenericBound::Trait(ptr, ast::TraitBoundModifier::Maybe) = b { self.space(); self.word_space("for ?"); self.print_trait_ref(&ptr.trait_ref); @@ -364,13 +369,13 @@ impl<'a> State<'a> { self.end(); // end inner head-block self.end(); // end outer head-block } - ast::ItemKind::MacCall(ref mac) => { + ast::ItemKind::MacCall(mac) => { self.print_mac(mac); if mac.args.need_semicolon() { self.word(";"); } } - ast::ItemKind::MacroDef(ref macro_def) => { + ast::ItemKind::MacroDef(macro_def) => { self.print_mac_def(macro_def, &item.ident, item.span, |state| { state.print_visibility(&item.vis) }); @@ -412,11 +417,11 @@ impl<'a> State<'a> { } pub(crate) fn print_visibility(&mut self, vis: &ast::Visibility) { - match vis.kind { + match &vis.kind { ast::VisibilityKind::Public => self.word_nbsp("pub"), - ast::VisibilityKind::Restricted { ref path, id: _, shorthand } => { + ast::VisibilityKind::Restricted { path, shorthand, .. } => { let path = Self::to_string(|s| s.print_path(path, false, 0)); - if shorthand && (path == "crate" || path == "self" || path == "super") { + if *shorthand && (path == "crate" || path == "self" || path == "super") { self.word_nbsp(format!("pub({})", path)) } else { self.word_nbsp(format!("pub(in {})", path)) @@ -465,7 +470,7 @@ impl<'a> State<'a> { ) { self.print_ident(ident); self.print_generic_params(&generics.params); - match struct_def { + match &struct_def { ast::VariantData::Tuple(..) | ast::VariantData::Unit(..) => { if let ast::VariantData::Tuple(..) = struct_def { self.popen(); @@ -484,7 +489,7 @@ impl<'a> State<'a> { self.end(); self.end(); // Close the outer-box. } - ast::VariantData::Struct(ref fields, ..) => { + ast::VariantData::Struct(fields, ..) => { self.print_where_clause(&generics.where_clause); self.print_record_struct_body(fields, span); } @@ -496,7 +501,7 @@ impl<'a> State<'a> { self.print_visibility(&v.vis); let generics = ast::Generics::default(); self.print_struct(&v.data, &generics, v.ident, v.span, false); - if let Some(ref d) = v.disr_expr { + if let Some(d) = &v.disr_expr { self.space(); self.word_space("="); self.print_expr(&d.value) @@ -657,10 +662,10 @@ impl<'a> State<'a> { } fn print_use_tree(&mut self, tree: &ast::UseTree) { - match tree.kind { + match &tree.kind { ast::UseTreeKind::Simple(rename, ..) => { self.print_path(&tree.prefix, false, 0); - if let Some(rename) = rename { + if let &Some(rename) = rename { self.nbsp(); self.word_nbsp("as"); self.print_ident(rename); @@ -673,7 +678,7 @@ impl<'a> State<'a> { } self.word("*"); } - ast::UseTreeKind::Nested(ref items) => { + ast::UseTreeKind::Nested(items) => { if !tree.prefix.segments.is_empty() { self.print_path(&tree.prefix, false, 0); self.word("::"); From c8f3203c46c4b95a9eaff3ff8bb99982b682db0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Tue, 29 Nov 2022 11:26:40 +0100 Subject: [PATCH 10/19] hermit: Fix fuzzy_provenance_casts --- library/std/src/sys/hermit/thread.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index e53a1fea6a0dc..8f65544a9e894 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -5,6 +5,7 @@ use crate::ffi::CStr; use crate::io; use crate::mem; use crate::num::NonZeroUsize; +use crate::ptr; use crate::sys::hermit::abi; use crate::sys::hermit::thread_local_dtor::run_dtors; use crate::time::Duration; @@ -47,7 +48,7 @@ impl Thread { extern "C" fn thread_start(main: usize) { unsafe { // Finally, let's run some code. - Box::from_raw(main as *mut Box)(); + Box::from_raw(ptr::from_exposed_addr::>(main).cast_mut())(); // run all destructors run_dtors(); From 0a4e5efe6f6e6d84147b3da689f99b2b9750834c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Kr=C3=B6ning?= Date: Tue, 29 Nov 2022 11:27:25 +0100 Subject: [PATCH 11/19] hermit: Remove unused exports --- library/std/src/sys/hermit/fs.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/library/std/src/sys/hermit/fs.rs b/library/std/src/sys/hermit/fs.rs index af297ff1ec75b..6fb92c037ee4f 100644 --- a/library/std/src/sys/hermit/fs.rs +++ b/library/std/src/sys/hermit/fs.rs @@ -1,10 +1,8 @@ -use crate::convert::TryFrom; -use crate::ffi::{CStr, CString, OsString}; +use crate::ffi::{CStr, OsString}; use crate::fmt; use crate::hash::{Hash, Hasher}; use crate::io::{self, Error, ErrorKind}; use crate::io::{BorrowedCursor, IoSlice, IoSliceMut, SeekFrom}; -use crate::os::unix::ffi::OsStrExt; use crate::path::{Path, PathBuf}; use crate::sys::common::small_c_string::run_path_with_cstr; use crate::sys::cvt; From 050cee48f83b39a0f532e4905d02f07716bf2ee3 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 29 Nov 2022 11:52:48 +0000 Subject: [PATCH 12/19] Replace a macro with a function --- compiler/rustc_serialize/src/leb128.rs | 19 ++++++++----------- compiler/rustc_serialize/src/opaque.rs | 10 +++++----- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index a6cdd32f23b8e..c5297bff193c3 100644 --- a/compiler/rustc_serialize/src/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs @@ -1,22 +1,19 @@ -#![macro_use] - -macro_rules! max_leb128_len { - ($int_ty:ty) => { - // The longest LEB128 encoding for an integer uses 7 bits per byte. - (std::mem::size_of::<$int_ty>() * 8 + 6) / 7 - }; +/// Returns the longest LEB128 encoding for `T`, assuming `T` is an integer type +pub const fn max_leb128_len() -> usize { + // The longest LEB128 encoding for an integer uses 7 bits per byte. + (std::mem::size_of::() * 8 + 6) / 7 } /// Returns the longest LEB128 encoding of all supported integer types. -pub const fn max_leb128_len() -> usize { - max_leb128_len!(u128) +pub const fn max_max_leb128_len() -> usize { + max_leb128_len::() } macro_rules! impl_write_unsigned_leb128 { ($fn_name:ident, $int_ty:ty) => { #[inline] pub fn $fn_name( - out: &mut [::std::mem::MaybeUninit; max_leb128_len!($int_ty)], + out: &mut [::std::mem::MaybeUninit; max_leb128_len::<$int_ty>()], mut value: $int_ty, ) -> &[u8] { let mut i = 0; @@ -90,7 +87,7 @@ macro_rules! impl_write_signed_leb128 { ($fn_name:ident, $int_ty:ty) => { #[inline] pub fn $fn_name( - out: &mut [::std::mem::MaybeUninit; max_leb128_len!($int_ty)], + out: &mut [::std::mem::MaybeUninit; max_leb128_len::<$int_ty>()], mut value: $int_ty, ) -> &[u8] { let mut i = 0; diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 7c54df809f179..7cd513e1eb925 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -1,4 +1,4 @@ -use crate::leb128::{self, max_leb128_len}; +use crate::leb128::{self, max_max_leb128_len}; use crate::serialize::{Decodable, Decoder, Encodable, Encoder}; use std::convert::TryInto; use std::fs::File; @@ -32,7 +32,7 @@ impl MemEncoder { macro_rules! write_leb128 { ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{ - const MAX_ENCODED_LEN: usize = max_leb128_len!($int_ty); + const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); let old_len = $enc.data.len(); if MAX_ENCODED_LEN > $enc.data.capacity() - old_len { @@ -186,12 +186,12 @@ impl FileEncoder { pub fn with_capacity>(path: P, capacity: usize) -> io::Result { // Require capacity at least as large as the largest LEB128 encoding // here, so that we don't have to check or handle this on every write. - assert!(capacity >= max_leb128_len()); + assert!(capacity >= max_max_leb128_len()); // Require capacity small enough such that some capacity checks can be // done using guaranteed non-overflowing add rather than sub, which // shaves an instruction off those code paths (on x86 at least). - assert!(capacity <= usize::MAX - max_leb128_len()); + assert!(capacity <= usize::MAX - max_max_leb128_len()); // Create the file for reading and writing, because some encoders do both // (e.g. the metadata encoder when -Zmeta-stats is enabled) @@ -411,7 +411,7 @@ impl Drop for FileEncoder { macro_rules! file_encoder_write_leb128 { ($enc:expr, $value:expr, $int_ty:ty, $fun:ident) => {{ - const MAX_ENCODED_LEN: usize = max_leb128_len!($int_ty); + const MAX_ENCODED_LEN: usize = $crate::leb128::max_leb128_len::<$int_ty>(); // We ensure this during `FileEncoder` construction. debug_assert!($enc.capacity() >= MAX_ENCODED_LEN); From 537488efd6f0be7240b5e2d08cae4af5db7162ab Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 25 Nov 2022 16:35:27 -0300 Subject: [PATCH 13/19] Make inferred_outlives_crate return Clause --- compiler/rustc_hir_analysis/src/collect.rs | 12 +++++---- .../rustc_hir_analysis/src/outlives/mod.rs | 26 ++++++------------- compiler/rustc_lint/src/builtin.rs | 20 ++++++-------- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/ty/codec.rs | 8 ++++++ compiler/rustc_middle/src/ty/mod.rs | 9 ++++++- compiler/rustc_middle/src/ty/parameterized.rs | 3 ++- .../rustc_query_impl/src/on_disk_cache.rs | 6 +++++ 9 files changed, 49 insertions(+), 39 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 638dd6d756b58..d623e72613944 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -33,7 +33,7 @@ use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs} use rustc_middle::mir::mono::Linkage; use rustc_middle::ty::query::Providers; use rustc_middle::ty::util::{Discr, IntTypeExt}; -use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, Ty, TyCtxt}; +use rustc_middle::ty::{self, AdtKind, Const, DefIdTree, IsSuggestable, ToPredicate, Ty, TyCtxt}; use rustc_session::lint; use rustc_session::parse::feature_err; use rustc_span::symbol::{kw, sym, Ident, Symbol}; @@ -1366,12 +1366,14 @@ fn predicates_defined_on(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicate "predicates_defined_on: inferred_outlives_of({:?}) = {:?}", def_id, inferred_outlives, ); + let inferred_outlives_iter = + inferred_outlives.iter().map(|(clause, span)| ((*clause).to_predicate(tcx), *span)); if result.predicates.is_empty() { - result.predicates = inferred_outlives; + result.predicates = tcx.arena.alloc_from_iter(inferred_outlives_iter); } else { - result.predicates = tcx - .arena - .alloc_from_iter(result.predicates.iter().chain(inferred_outlives).copied()); + result.predicates = tcx.arena.alloc_from_iter( + result.predicates.into_iter().copied().chain(inferred_outlives_iter), + ); } } diff --git a/compiler/rustc_hir_analysis/src/outlives/mod.rs b/compiler/rustc_hir_analysis/src/outlives/mod.rs index c8f37176836c5..81fe32000d307 100644 --- a/compiler/rustc_hir_analysis/src/outlives/mod.rs +++ b/compiler/rustc_hir_analysis/src/outlives/mod.rs @@ -3,7 +3,7 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::GenericArgKind; -use rustc_middle::ty::{self, CratePredicatesMap, ToPredicate, TyCtxt}; +use rustc_middle::ty::{self, CratePredicatesMap, TyCtxt}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -17,7 +17,7 @@ pub fn provide(providers: &mut Providers) { *providers = Providers { inferred_outlives_of, inferred_outlives_crate, ..*providers }; } -fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate<'_>, Span)] { +fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Clause<'_>, Span)] { let id = tcx.hir().local_def_id_to_hir_id(item_def_id.expect_local()); if matches!(tcx.def_kind(item_def_id), hir::def::DefKind::AnonConst) && tcx.lazy_normalization() @@ -50,12 +50,10 @@ fn inferred_outlives_of(tcx: TyCtxt<'_>, item_def_id: DefId) -> &[(ty::Predicate if tcx.has_attr(item_def_id, sym::rustc_outlives) { let mut pred: Vec = predicates .iter() - .map(|(out_pred, _)| match out_pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::RegionOutlives(p)) => { - p.to_string() - } - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(p)) => p.to_string(), - err => bug!("unexpected predicate {:?}", err), + .map(|(out_pred, _)| match out_pred { + ty::Clause::RegionOutlives(p) => p.to_string(), + ty::Clause::TypeOutlives(p) => p.to_string(), + err => bug!("unexpected clause {:?}", err), }) .collect(); pred.sort(); @@ -103,19 +101,11 @@ fn inferred_outlives_crate(tcx: TyCtxt<'_>, (): ()) -> CratePredicatesMap<'_> { |(ty::OutlivesPredicate(kind1, region2), &span)| { match kind1.unpack() { GenericArgKind::Type(ty1) => Some(( - ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::TypeOutlives( - ty::OutlivesPredicate(ty1, *region2), - ))) - .to_predicate(tcx), + ty::Clause::TypeOutlives(ty::OutlivesPredicate(ty1, *region2)), span, )), GenericArgKind::Lifetime(region1) => Some(( - ty::Binder::dummy(ty::PredicateKind::Clause( - ty::Clause::RegionOutlives(ty::OutlivesPredicate( - region1, *region2, - )), - )) - .to_predicate(tcx), + ty::Clause::RegionOutlives(ty::OutlivesPredicate(region1, *region2)), span, )), GenericArgKind::Const(_) => { diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 93d81125f4885..825093384fba7 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2046,16 +2046,13 @@ declare_lint_pass!(ExplicitOutlivesRequirements => [EXPLICIT_OUTLIVES_REQUIREMEN impl ExplicitOutlivesRequirements { fn lifetimes_outliving_lifetime<'tcx>( - inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], + inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], def_id: DefId, ) -> Vec> { inferred_outlives .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::RegionOutlives(ty::OutlivesPredicate( - a, - b, - ))) => match *a { + .filter_map(|(clause, _)| match *clause { + ty::Clause::RegionOutlives(ty::OutlivesPredicate(a, b)) => match *a { ty::ReEarlyBound(ebr) if ebr.def_id == def_id => Some(b), _ => None, }, @@ -2065,16 +2062,15 @@ impl ExplicitOutlivesRequirements { } fn lifetimes_outliving_type<'tcx>( - inferred_outlives: &'tcx [(ty::Predicate<'tcx>, Span)], + inferred_outlives: &'tcx [(ty::Clause<'tcx>, Span)], index: u32, ) -> Vec> { inferred_outlives .iter() - .filter_map(|(pred, _)| match pred.kind().skip_binder() { - ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate( - a, - b, - ))) => a.is_param(index).then_some(b), + .filter_map(|(clause, _)| match *clause { + ty::Clause::TypeOutlives(ty::OutlivesPredicate(a, b)) => { + a.is_param(index).then_some(b) + } _ => None, }) .collect() diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index c51b8f96c7151..6b60577c9023f 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -353,7 +353,7 @@ define_tables! { explicit_predicates_of: Table>>, generics_of: Table>, // As an optimization, a missing entry indicates an empty `&[]`. - inferred_outlives_of: Table, Span)>>, + inferred_outlives_of: Table, Span)>>, super_predicates_of: Table>>, type_of: Table>>, variances_of: Table>, diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 38b72ec923193..e1220320eea1b 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -562,7 +562,7 @@ rustc_queries! { /// Returns the inferred outlives predicates (e.g., for `struct /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). - query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Predicate<'tcx>, Span)] { + query inferred_outlives_of(key: DefId) -> &'tcx [(ty::Clause<'tcx>, Span)] { desc { |tcx| "computing inferred outlives predicates of `{}`", tcx.def_path_str(key) } cache_on_disk_if { key.is_local() } separate_provide_extern diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index b22b3961f34ea..75f2d45eadb81 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -345,6 +345,14 @@ impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> } } +impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for [(ty::Clause<'tcx>, Span)] { + fn decode(decoder: &mut D) -> &'tcx Self { + decoder.interner().arena.alloc_from_iter( + (0..decoder.read_usize()).map(|_| Decodable::decode(decoder)).collect::>(), + ) + } +} + impl<'tcx, D: TyDecoder>> RefDecodable<'tcx, D> for ty::List { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 595b73986a87b..7be9fee3b0cf6 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -734,7 +734,7 @@ pub struct CratePredicatesMap<'tcx> { /// For each struct with outlive bounds, maps to a vector of the /// predicate of its outlive bounds. If an item has no outlives /// bounds, it will have no entry. - pub predicates: FxHashMap, Span)]>, + pub predicates: FxHashMap, Span)]>, } impl<'tcx> Predicate<'tcx> { @@ -1167,6 +1167,13 @@ impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, PredicateKind<'tc } } +impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Clause<'tcx> { + #[inline(always)] + fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { + tcx.mk_predicate(ty::Binder::dummy(ty::PredicateKind::Clause(self))) + } +} + impl<'tcx> ToPredicate<'tcx, Predicate<'tcx>> for Binder<'tcx, TraitRef<'tcx>> { #[inline(always)] fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> { diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs index b2bcf0e29cd9d..c7d6c6abd1c22 100644 --- a/compiler/rustc_middle/src/ty/parameterized.rs +++ b/compiler/rustc_middle/src/ty/parameterized.rs @@ -5,7 +5,7 @@ use rustc_index::vec::{Idx, IndexVec}; use crate::middle::exported_symbols::ExportedSymbol; use crate::mir::Body; use crate::ty::{ - self, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty, + self, Clause, Const, FnSig, GeneratorDiagnosticData, GenericPredicates, Predicate, TraitRef, Ty, }; pub trait ParameterizedOverTcx: 'static { @@ -121,6 +121,7 @@ parameterized_over_tcx! { TraitRef, Const, Predicate, + Clause, GeneratorDiagnosticData, Body, ExportedSymbol, diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs index c61d2a9c2d0c6..ac9653b90071c 100644 --- a/compiler/rustc_query_impl/src/on_disk_cache.rs +++ b/compiler/rustc_query_impl/src/on_disk_cache.rs @@ -818,6 +818,12 @@ impl<'a, 'tcx> Decodable> for &'tcx [(ty::Predicate<'tcx> } } +impl<'a, 'tcx> Decodable> for &'tcx [(ty::Clause<'tcx>, Span)] { + fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { + RefDecodable::decode(d) + } +} + impl<'a, 'tcx> Decodable> for &'tcx [rustc_ast::InlineAsmTemplatePiece] { fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self { RefDecodable::decode(d) From 8c0951511b25dbe911dd7b1f880deaf06aad0351 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Tue, 29 Nov 2022 17:58:09 +0000 Subject: [PATCH 14/19] rename `{max=>largest}_max_leb128_len` --- compiler/rustc_serialize/src/leb128.rs | 6 +++--- compiler/rustc_serialize/src/opaque.rs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_serialize/src/leb128.rs b/compiler/rustc_serialize/src/leb128.rs index c5297bff193c3..7dad9aa01fafd 100644 --- a/compiler/rustc_serialize/src/leb128.rs +++ b/compiler/rustc_serialize/src/leb128.rs @@ -1,11 +1,11 @@ -/// Returns the longest LEB128 encoding for `T`, assuming `T` is an integer type +/// Returns the length of the longest LEB128 encoding for `T`, assuming `T` is an integer type pub const fn max_leb128_len() -> usize { // The longest LEB128 encoding for an integer uses 7 bits per byte. (std::mem::size_of::() * 8 + 6) / 7 } -/// Returns the longest LEB128 encoding of all supported integer types. -pub const fn max_max_leb128_len() -> usize { +/// Returns the length of the longest LEB128 encoding of all supported integer types. +pub const fn largest_max_leb128_len() -> usize { max_leb128_len::() } diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs index 7cd513e1eb925..0afeb86fceb24 100644 --- a/compiler/rustc_serialize/src/opaque.rs +++ b/compiler/rustc_serialize/src/opaque.rs @@ -1,4 +1,4 @@ -use crate::leb128::{self, max_max_leb128_len}; +use crate::leb128::{self, largest_max_leb128_len}; use crate::serialize::{Decodable, Decoder, Encodable, Encoder}; use std::convert::TryInto; use std::fs::File; @@ -186,12 +186,12 @@ impl FileEncoder { pub fn with_capacity>(path: P, capacity: usize) -> io::Result { // Require capacity at least as large as the largest LEB128 encoding // here, so that we don't have to check or handle this on every write. - assert!(capacity >= max_max_leb128_len()); + assert!(capacity >= largest_max_leb128_len()); // Require capacity small enough such that some capacity checks can be // done using guaranteed non-overflowing add rather than sub, which // shaves an instruction off those code paths (on x86 at least). - assert!(capacity <= usize::MAX - max_max_leb128_len()); + assert!(capacity <= usize::MAX - largest_max_leb128_len()); // Create the file for reading and writing, because some encoders do both // (e.g. the metadata encoder when -Zmeta-stats is enabled) From 1b4012e3043c2431c57435d0017832fa3f4bb0c6 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Tue, 29 Nov 2022 22:01:49 +0400 Subject: [PATCH 15/19] add `FIXME:` where it belongs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit suggestion from a friend!! 🐸 Co-authored-by: Michael Goulet --- compiler/rustc_ast_pretty/src/pprust/state.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs index 0fe1045c244cb..374e0a97063e3 100644 --- a/compiler/rustc_ast_pretty/src/pprust/state.rs +++ b/compiler/rustc_ast_pretty/src/pprust/state.rs @@ -64,7 +64,7 @@ impl<'a> Comments<'a> { Comments { sm, comments, current: 0 } } - // This shouldn't probably clone lmao + // FIXME: This shouldn't probably clone lmao pub fn next(&self) -> Option { self.comments.get(self.current).cloned() } From edf5cce5a40202df78ecf47cf52057e0eb93c2ff Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Tue, 29 Nov 2022 11:13:44 -0700 Subject: [PATCH 16/19] rustdoc: use shorthand background for rustdoc toggle CSS --- src/librustdoc/html/static/css/rustdoc.css | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index cf5592da43205..de882e66f43de 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -1511,13 +1511,11 @@ details.rustdoc-toggle > summary.hideme > span { } details.rustdoc-toggle > summary::before { - background-image: url("toggle-plus-1092eb4930d581b0.svg"); + background: url("toggle-plus-1092eb4930d581b0.svg") no-repeat top left; content: ""; cursor: pointer; width: 16px; height: 16px; - background-repeat: no-repeat; - background-position: top left; display: inline-block; vertical-align: middle; opacity: .5; @@ -1598,11 +1596,9 @@ details.rustdoc-toggle[open] > summary.hideme > span { details.rustdoc-toggle[open] > summary::before, details.rustdoc-toggle[open] > summary.hideme::before { - background-image: url("toggle-minus-31bbd6e4c77f5c96.svg"); + background: url("toggle-minus-31bbd6e4c77f5c96.svg") no-repeat top left; width: 16px; height: 16px; - background-repeat: no-repeat; - background-position: top left; display: inline-block; content: ""; } From 9512446a00dd203196dc0e716bd34d107299bc1d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Mon, 14 Nov 2022 23:25:41 +0000 Subject: [PATCH 17/19] Explain why rematch_impl fails to be infallible --- compiler/rustc_trait_selection/src/traits/select/mod.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a2d2d44fbc28f..a3c182d4becc9 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2140,6 +2140,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { match self.match_impl(impl_def_id, impl_trait_ref, obligation) { Ok(substs) => substs, Err(()) => { + // FIXME: A rematch may fail when a candidate cache hit occurs + // on thefreshened form of the trait predicate, but the match + // fails for some reason that is not captured in the freshened + // cache key. For example, equating an impl trait ref against + // the placeholder trait ref may fail due the Generalizer relation + // raising a CyclicalTy error due to a sub_root_var relation + // for a variable being generalized... self.infcx.tcx.sess.delay_span_bug( obligation.cause.span, &format!( From bb982df771d02d2b6d2c30bd56cd2d25ba423a2b Mon Sep 17 00:00:00 2001 From: lcnr Date: Tue, 29 Nov 2022 20:32:48 +0000 Subject: [PATCH 18/19] move `candidate_from_obligation` out of assembly it doesn't belong there as it also does winnowing --- .../src/traits/select/candidate_assembly.rs | 213 +----------------- .../src/traits/select/mod.rs | 204 +++++++++++++++++ 2 files changed, 207 insertions(+), 210 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index 627ed4674b0e9..fe5135661b5f8 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -9,225 +9,18 @@ use hir::LangItem; use rustc_hir as hir; use rustc_infer::traits::ObligationCause; use rustc_infer::traits::{Obligation, SelectionError, TraitObligation}; -use rustc_middle::ty::print::with_no_trimmed_paths; use rustc_middle::ty::{self, Ty, TypeVisitable}; use rustc_target::spec::abi::Abi; use crate::traits; -use crate::traits::coherence::Conflict; use crate::traits::query::evaluate_obligation::InferCtxtExt; -use crate::traits::{util, SelectionResult}; -use crate::traits::{ErrorReporting, Overflow, Unimplemented}; +use crate::traits::util; use super::BuiltinImplConditions; -use super::IntercrateAmbiguityCause; -use super::OverflowError; -use super::SelectionCandidate::{self, *}; -use super::{EvaluatedCandidate, SelectionCandidateSet, SelectionContext, TraitObligationStack}; +use super::SelectionCandidate::*; +use super::{SelectionCandidateSet, SelectionContext, TraitObligationStack}; impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { - #[instrument(level = "debug", skip(self), ret)] - pub(super) fn candidate_from_obligation<'o>( - &mut self, - stack: &TraitObligationStack<'o, 'tcx>, - ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - // Watch out for overflow. This intentionally bypasses (and does - // not update) the cache. - self.check_recursion_limit(&stack.obligation, &stack.obligation)?; - - // Check the cache. Note that we freshen the trait-ref - // separately rather than using `stack.fresh_trait_ref` -- - // this is because we want the unbound variables to be - // replaced with fresh types starting from index 0. - let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate); - debug!(?cache_fresh_trait_pred); - debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars()); - - if let Some(c) = - self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred) - { - debug!("CACHE HIT"); - return c; - } - - // If no match, compute result and insert into cache. - // - // FIXME(nikomatsakis) -- this cache is not taking into - // account cycles that may have occurred in forming the - // candidate. I don't know of any specific problems that - // result but it seems awfully suspicious. - let (candidate, dep_node) = - self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); - - debug!("CACHE MISS"); - self.insert_candidate_cache( - stack.obligation.param_env, - cache_fresh_trait_pred, - dep_node, - candidate.clone(), - ); - candidate - } - - fn candidate_from_obligation_no_cache<'o>( - &mut self, - stack: &TraitObligationStack<'o, 'tcx>, - ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { - if let Err(conflict) = self.is_knowable(stack) { - debug!("coherence stage: not knowable"); - if self.intercrate_ambiguity_causes.is_some() { - debug!("evaluate_stack: intercrate_ambiguity_causes is some"); - // Heuristics: show the diagnostics when there are no candidates in crate. - if let Ok(candidate_set) = self.assemble_candidates(stack) { - let mut no_candidates_apply = true; - - for c in candidate_set.vec.iter() { - if self.evaluate_candidate(stack, &c)?.may_apply() { - no_candidates_apply = false; - break; - } - } - - if !candidate_set.ambiguous && no_candidates_apply { - let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; - let self_ty = trait_ref.self_ty(); - let (trait_desc, self_desc) = with_no_trimmed_paths!({ - let trait_desc = trait_ref.print_only_trait_path().to_string(); - let self_desc = if self_ty.has_concrete_skeleton() { - Some(self_ty.to_string()) - } else { - None - }; - (trait_desc, self_desc) - }); - let cause = if let Conflict::Upstream = conflict { - IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } - } else { - IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } - }; - debug!(?cause, "evaluate_stack: pushing cause"); - self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); - } - } - } - return Ok(None); - } - - let candidate_set = self.assemble_candidates(stack)?; - - if candidate_set.ambiguous { - debug!("candidate set contains ambig"); - return Ok(None); - } - - let candidates = candidate_set.vec; - - debug!(?stack, ?candidates, "assembled {} candidates", candidates.len()); - - // At this point, we know that each of the entries in the - // candidate set is *individually* applicable. Now we have to - // figure out if they contain mutual incompatibilities. This - // frequently arises if we have an unconstrained input type -- - // for example, we are looking for `$0: Eq` where `$0` is some - // unconstrained type variable. In that case, we'll get a - // candidate which assumes $0 == int, one that assumes `$0 == - // usize`, etc. This spells an ambiguity. - - let mut candidates = self.filter_impls(candidates, stack.obligation); - - // If there is more than one candidate, first winnow them down - // by considering extra conditions (nested obligations and so - // forth). We don't winnow if there is exactly one - // candidate. This is a relatively minor distinction but it - // can lead to better inference and error-reporting. An - // example would be if there was an impl: - // - // impl Vec { fn push_clone(...) { ... } } - // - // and we were to see some code `foo.push_clone()` where `boo` - // is a `Vec` and `Bar` does not implement `Clone`. If - // we were to winnow, we'd wind up with zero candidates. - // Instead, we select the right impl now but report "`Bar` does - // not implement `Clone`". - if candidates.len() == 1 { - return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation); - } - - // Winnow, but record the exact outcome of evaluation, which - // is needed for specialization. Propagate overflow if it occurs. - let mut candidates = candidates - .into_iter() - .map(|c| match self.evaluate_candidate(stack, &c) { - Ok(eval) if eval.may_apply() => { - Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) - } - Ok(_) => Ok(None), - Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)), - Err(OverflowError::ErrorReporting) => Err(ErrorReporting), - Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))), - }) - .flat_map(Result::transpose) - .collect::, _>>()?; - - debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len()); - - let needs_infer = stack.obligation.predicate.has_non_region_infer(); - - // If there are STILL multiple candidates, we can further - // reduce the list by dropping duplicates -- including - // resolving specializations. - if candidates.len() > 1 { - let mut i = 0; - while i < candidates.len() { - let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| { - self.candidate_should_be_dropped_in_favor_of( - &candidates[i], - &candidates[j], - needs_infer, - ) - }); - if is_dup { - debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len()); - candidates.swap_remove(i); - } else { - debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len()); - i += 1; - - // If there are *STILL* multiple candidates, give up - // and report ambiguity. - if i > 1 { - debug!("multiple matches, ambig"); - return Ok(None); - } - } - } - } - - // If there are *NO* candidates, then there are no impls -- - // that we know of, anyway. Note that in the case where there - // are unbound type variables within the obligation, it might - // be the case that you could still satisfy the obligation - // from another crate by instantiating the type variables with - // a type from another crate that does have an impl. This case - // is checked for in `evaluate_stack` (and hence users - // who might care about this case, like coherence, should use - // that function). - if candidates.is_empty() { - // If there's an error type, 'downgrade' our result from - // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid - // emitting additional spurious errors, since we're guaranteed - // to have emitted at least one. - if stack.obligation.predicate.references_error() { - debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous"); - return Ok(None); - } - return Err(Unimplemented); - } - - // Just one candidate left. - self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation) - } - #[instrument(skip(self, stack), level = "debug")] pub(super) fn assemble_candidates<'o>( &mut self, diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index a2d2d44fbc28f..48f94fc11a636 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -30,6 +30,7 @@ use crate::traits::error_reporting::TypeErrCtxtExt; use crate::traits::project::ProjectAndUnifyResult; use crate::traits::project::ProjectionCacheKeyExt; use crate::traits::ProjectionCacheKey; +use crate::traits::Unimplemented; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_data_structures::stack::ensure_sufficient_stack; @@ -55,6 +56,7 @@ use std::fmt::{self, Display}; use std::iter; pub use rustc_middle::traits::select::*; +use rustc_middle::ty::print::with_no_trimmed_paths; mod candidate_assembly; mod confirmation; @@ -305,6 +307,208 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { self.candidate_from_obligation(&stack) } + #[instrument(level = "debug", skip(self), ret)] + fn candidate_from_obligation<'o>( + &mut self, + stack: &TraitObligationStack<'o, 'tcx>, + ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { + // Watch out for overflow. This intentionally bypasses (and does + // not update) the cache. + self.check_recursion_limit(&stack.obligation, &stack.obligation)?; + + // Check the cache. Note that we freshen the trait-ref + // separately rather than using `stack.fresh_trait_ref` -- + // this is because we want the unbound variables to be + // replaced with fresh types starting from index 0. + let cache_fresh_trait_pred = self.infcx.freshen(stack.obligation.predicate); + debug!(?cache_fresh_trait_pred); + debug_assert!(!stack.obligation.predicate.has_escaping_bound_vars()); + + if let Some(c) = + self.check_candidate_cache(stack.obligation.param_env, cache_fresh_trait_pred) + { + debug!("CACHE HIT"); + return c; + } + + // If no match, compute result and insert into cache. + // + // FIXME(nikomatsakis) -- this cache is not taking into + // account cycles that may have occurred in forming the + // candidate. I don't know of any specific problems that + // result but it seems awfully suspicious. + let (candidate, dep_node) = + self.in_task(|this| this.candidate_from_obligation_no_cache(stack)); + + debug!("CACHE MISS"); + self.insert_candidate_cache( + stack.obligation.param_env, + cache_fresh_trait_pred, + dep_node, + candidate.clone(), + ); + candidate + } + + fn candidate_from_obligation_no_cache<'o>( + &mut self, + stack: &TraitObligationStack<'o, 'tcx>, + ) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { + if let Err(conflict) = self.is_knowable(stack) { + debug!("coherence stage: not knowable"); + if self.intercrate_ambiguity_causes.is_some() { + debug!("evaluate_stack: intercrate_ambiguity_causes is some"); + // Heuristics: show the diagnostics when there are no candidates in crate. + if let Ok(candidate_set) = self.assemble_candidates(stack) { + let mut no_candidates_apply = true; + + for c in candidate_set.vec.iter() { + if self.evaluate_candidate(stack, &c)?.may_apply() { + no_candidates_apply = false; + break; + } + } + + if !candidate_set.ambiguous && no_candidates_apply { + let trait_ref = stack.obligation.predicate.skip_binder().trait_ref; + let self_ty = trait_ref.self_ty(); + let (trait_desc, self_desc) = with_no_trimmed_paths!({ + let trait_desc = trait_ref.print_only_trait_path().to_string(); + let self_desc = if self_ty.has_concrete_skeleton() { + Some(self_ty.to_string()) + } else { + None + }; + (trait_desc, self_desc) + }); + let cause = if let Conflict::Upstream = conflict { + IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc } + } else { + IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc } + }; + debug!(?cause, "evaluate_stack: pushing cause"); + self.intercrate_ambiguity_causes.as_mut().unwrap().insert(cause); + } + } + } + return Ok(None); + } + + let candidate_set = self.assemble_candidates(stack)?; + + if candidate_set.ambiguous { + debug!("candidate set contains ambig"); + return Ok(None); + } + + let candidates = candidate_set.vec; + + debug!(?stack, ?candidates, "assembled {} candidates", candidates.len()); + + // At this point, we know that each of the entries in the + // candidate set is *individually* applicable. Now we have to + // figure out if they contain mutual incompatibilities. This + // frequently arises if we have an unconstrained input type -- + // for example, we are looking for `$0: Eq` where `$0` is some + // unconstrained type variable. In that case, we'll get a + // candidate which assumes $0 == int, one that assumes `$0 == + // usize`, etc. This spells an ambiguity. + + let mut candidates = self.filter_impls(candidates, stack.obligation); + + // If there is more than one candidate, first winnow them down + // by considering extra conditions (nested obligations and so + // forth). We don't winnow if there is exactly one + // candidate. This is a relatively minor distinction but it + // can lead to better inference and error-reporting. An + // example would be if there was an impl: + // + // impl Vec { fn push_clone(...) { ... } } + // + // and we were to see some code `foo.push_clone()` where `boo` + // is a `Vec` and `Bar` does not implement `Clone`. If + // we were to winnow, we'd wind up with zero candidates. + // Instead, we select the right impl now but report "`Bar` does + // not implement `Clone`". + if candidates.len() == 1 { + return self.filter_reservation_impls(candidates.pop().unwrap(), stack.obligation); + } + + // Winnow, but record the exact outcome of evaluation, which + // is needed for specialization. Propagate overflow if it occurs. + let mut candidates = candidates + .into_iter() + .map(|c| match self.evaluate_candidate(stack, &c) { + Ok(eval) if eval.may_apply() => { + Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval })) + } + Ok(_) => Ok(None), + Err(OverflowError::Canonical) => Err(Overflow(OverflowError::Canonical)), + Err(OverflowError::ErrorReporting) => Err(ErrorReporting), + Err(OverflowError::Error(e)) => Err(Overflow(OverflowError::Error(e))), + }) + .flat_map(Result::transpose) + .collect::, _>>()?; + + debug!(?stack, ?candidates, "winnowed to {} candidates", candidates.len()); + + let needs_infer = stack.obligation.predicate.has_non_region_infer(); + + // If there are STILL multiple candidates, we can further + // reduce the list by dropping duplicates -- including + // resolving specializations. + if candidates.len() > 1 { + let mut i = 0; + while i < candidates.len() { + let is_dup = (0..candidates.len()).filter(|&j| i != j).any(|j| { + self.candidate_should_be_dropped_in_favor_of( + &candidates[i], + &candidates[j], + needs_infer, + ) + }); + if is_dup { + debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len()); + candidates.swap_remove(i); + } else { + debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len()); + i += 1; + + // If there are *STILL* multiple candidates, give up + // and report ambiguity. + if i > 1 { + debug!("multiple matches, ambig"); + return Ok(None); + } + } + } + } + + // If there are *NO* candidates, then there are no impls -- + // that we know of, anyway. Note that in the case where there + // are unbound type variables within the obligation, it might + // be the case that you could still satisfy the obligation + // from another crate by instantiating the type variables with + // a type from another crate that does have an impl. This case + // is checked for in `evaluate_stack` (and hence users + // who might care about this case, like coherence, should use + // that function). + if candidates.is_empty() { + // If there's an error type, 'downgrade' our result from + // `Err(Unimplemented)` to `Ok(None)`. This helps us avoid + // emitting additional spurious errors, since we're guaranteed + // to have emitted at least one. + if stack.obligation.predicate.references_error() { + debug!(?stack.obligation.predicate, "found error type in predicate, treating as ambiguous"); + return Ok(None); + } + return Err(Unimplemented); + } + + // Just one candidate left. + self.filter_reservation_impls(candidates.pop().unwrap().candidate, stack.obligation) + } + /////////////////////////////////////////////////////////////////////////// // EVALUATION // From 66180dfad8999661068ab7065b379fa044a114c6 Mon Sep 17 00:00:00 2001 From: Joe Neeman Date: Tue, 29 Nov 2022 14:33:55 -0600 Subject: [PATCH 19/19] Run patchelf also on rust-analyzer-proc-macro-srv. --- src/bootstrap/bootstrap.py | 1 + src/bootstrap/download.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py index 57128685d9110..2d5018d934e2e 100644 --- a/src/bootstrap/bootstrap.py +++ b/src/bootstrap/bootstrap.py @@ -441,6 +441,7 @@ def download_toolchain(self): self.fix_bin_or_dylib("{}/bin/rustc".format(bin_root)) self.fix_bin_or_dylib("{}/bin/rustdoc".format(bin_root)) + self.fix_bin_or_dylib("{}/libexec/rust-analyzer-proc-macro-srv".format(bin_root)) lib_dir = "{}/lib".format(bin_root) for lib in os.listdir(lib_dir): if lib.endswith(".so"): diff --git a/src/bootstrap/download.rs b/src/bootstrap/download.rs index d0f389df97344..6ae283f32a5f3 100644 --- a/src/bootstrap/download.rs +++ b/src/bootstrap/download.rs @@ -360,6 +360,7 @@ impl Config { self.fix_bin_or_dylib(&bin_root.join("bin").join("rustc")); self.fix_bin_or_dylib(&bin_root.join("bin").join("rustdoc")); + self.fix_bin_or_dylib(&bin_root.join("libexec").join("rust-analyzer-proc-macro-srv")); let lib_dir = bin_root.join("lib"); for lib in t!(fs::read_dir(&lib_dir), lib_dir.display().to_string()) { let lib = t!(lib);