From 111f2e8a39fce63c6daac7eae88023f1e87c15d4 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Wed, 2 Oct 2024 19:42:51 +0200 Subject: [PATCH 01/17] Fix target_os for mipsel-sony-psx Previously set to `target_os = "none"` and `target_env = "psx"`, but although the Playstation 1 is _close_ to a bare metal target in some regards, it's still very much an operating system, so we should set `target_os = "psx"`. This also matches the `mipsel-sony-psp` target, which sets `target_os = "psp"`. --- compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs | 3 +-- tests/ui/check-cfg/well-known-values.stderr | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs index c60bf65031128..843d9c50d5c53 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs @@ -14,8 +14,7 @@ pub(crate) fn target() -> Target { arch: "mips".into(), options: TargetOptions { - os: "none".into(), - env: "psx".into(), + os: "psx".into(), vendor: "sony".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), cpu: "mips1".into(), diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr index 14832e7ff4381..d981f74309419 100644 --- a/tests/ui/check-cfg/well-known-values.stderr +++ b/tests/ui/check-cfg/well-known-values.stderr @@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_env = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc` + = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -210,7 +210,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` LL | target_os = "_UNEXPECTED_VALUE", | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE` @@ -294,7 +294,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux` | | | help: there is a expected value with a similar name: `"linux"` | - = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` + = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm` = note: see for more information about checking conditional configuration warning: 30 warnings emitted From afe605957f04d9a2f453e40d673bde1f2cc037a7 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Thu, 3 Oct 2024 14:13:11 +0200 Subject: [PATCH 02/17] Add comment noting the situation with target_os = "psx" --- compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs index 843d9c50d5c53..1b8f9b71e9306 100644 --- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs +++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs @@ -14,6 +14,10 @@ pub(crate) fn target() -> Target { arch: "mips".into(), options: TargetOptions { + // The Playstation 1 is mostly bare-metal, but the BIOS does provide some a slight bit + // of functionality post load, so we still declare it as `cfg!(target_os = "psx")`. + // + // See for details. os: "psx".into(), vendor: "sony".into(), linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes), From e356279bdfe6840236877b298f0c577e0f9221ff Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 30 Oct 2024 02:28:37 +0000 Subject: [PATCH 03/17] Actually do validation for poly trait refs with ? modifier --- .../src/hir_ty_lowering/bounds.rs | 6 ---- .../src/hir_ty_lowering/dyn_compatibility.rs | 2 +- .../src/hir_ty_lowering/mod.rs | 11 ++++++- .../precise-capturing/bound-modifiers.rs | 2 -- .../precise-capturing/bound-modifiers.stderr | 32 ++++++------------- tests/ui/issues/issue-37534.rs | 3 +- tests/ui/issues/issue-37534.stderr | 13 ++------ .../trait-bounds/maybe-bound-generics-deny.rs | 4 +++ .../maybe-bound-generics-deny.stderr | 11 +++++++ .../trait-bounds/maybe-bound-has-path-args.rs | 7 ++++ .../maybe-bound-has-path-args.stderr | 17 ++++++++++ 11 files changed, 62 insertions(+), 46 deletions(-) create mode 100644 tests/ui/trait-bounds/maybe-bound-generics-deny.rs create mode 100644 tests/ui/trait-bounds/maybe-bound-generics-deny.stderr create mode 100644 tests/ui/trait-bounds/maybe-bound-has-path-args.rs create mode 100644 tests/ui/trait-bounds/maybe-bound-has-path-args.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs index a5709089db689..8cc475b536d17 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs @@ -168,12 +168,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { match hir_bound { hir::GenericBound::Trait(poly_trait_ref) => { let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers; - let polarity = match polarity { - rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, - rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, - rustc_ast::BoundPolarity::Maybe(_) => continue, - }; - let _ = self.lower_poly_trait_ref( &poly_trait_ref.trait_ref, poly_trait_ref.span, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs index f2ee4b0ccd417..7ece2632b6eb7 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs @@ -51,7 +51,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { &trait_bound.trait_ref, trait_bound.span, hir::BoundConstness::Never, - ty::PredicatePolarity::Positive, + hir::BoundPolarity::Positive, dummy_self, &mut bounds, PredicateFilter::SelfOnly, diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 2d0c3ec28c372..9b0d21bc00943 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -659,7 +659,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { trait_ref: &hir::TraitRef<'tcx>, span: Span, constness: hir::BoundConstness, - polarity: ty::PredicatePolarity, + polarity: hir::BoundPolarity, self_ty: Ty<'tcx>, bounds: &mut Bounds<'tcx>, predicate_filter: PredicateFilter, @@ -681,6 +681,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some(self_ty), ); + let polarity = match polarity { + rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, + rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, + rustc_ast::BoundPolarity::Maybe(_) => { + // No-op. + return arg_count; + } + }; + if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness && !self.tcx().is_const_trait(trait_def_id) { diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs index 4769581466898..46121308fa07c 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs @@ -3,8 +3,6 @@ fn polarity() -> impl Sized + ?use<> {} //~^ ERROR expected identifier, found keyword `use` //~| ERROR cannot find trait `r#use` in this scope -//~| WARN relaxing a default bound only does something for `?Sized` -//~| WARN relaxing a default bound only does something for `?Sized` fn asyncness() -> impl Sized + async use<> {} //~^ ERROR expected identifier, found keyword `use` diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr index aaebfe2a86e55..16e7470debf09 100644 --- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr +++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr @@ -5,19 +5,19 @@ LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:9:38 + --> $DIR/bound-modifiers.rs:7:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:14:38 + --> $DIR/bound-modifiers.rs:12:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ expected identifier, found keyword error: expected identifier, found keyword `use` - --> $DIR/bound-modifiers.rs:19:37 + --> $DIR/bound-modifiers.rs:17:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ expected identifier, found keyword @@ -29,25 +29,25 @@ LL | fn polarity() -> impl Sized + ?use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:9:38 + --> $DIR/bound-modifiers.rs:7:38 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:14:38 + --> $DIR/bound-modifiers.rs:12:38 | LL | fn constness() -> impl Sized + const use<> {} | ^^^ not found in this scope error[E0405]: cannot find trait `r#use` in this scope - --> $DIR/bound-modifiers.rs:19:37 + --> $DIR/bound-modifiers.rs:17:37 | LL | fn binder() -> impl Sized + for<'a> use<> {} | ^^^ not found in this scope error[E0658]: async closures are unstable - --> $DIR/bound-modifiers.rs:9:32 + --> $DIR/bound-modifiers.rs:7:32 | LL | fn asyncness() -> impl Sized + async use<> {} | ^^^^^ @@ -58,7 +58,7 @@ LL | fn asyncness() -> impl Sized + async use<> {} = help: to use an async block, remove the `||`: `async {` error[E0658]: const trait impls are experimental - --> $DIR/bound-modifiers.rs:14:32 + --> $DIR/bound-modifiers.rs:12:32 | LL | fn constness() -> impl Sized + const use<> {} | ^^^^^ @@ -67,21 +67,7 @@ LL | fn constness() -> impl Sized + const use<> {} = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date -warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/bound-modifiers.rs:3:31 - | -LL | fn polarity() -> impl Sized + ?use<> {} - | ^^^^^^ - -warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default - --> $DIR/bound-modifiers.rs:3:31 - | -LL | fn polarity() -> impl Sized + ?use<> {} - | ^^^^^^ - | - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 10 previous errors; 2 warnings emitted +error: aborting due to 10 previous errors Some errors have detailed explanations: E0405, E0658. For more information about an error, try `rustc --explain E0405`. diff --git a/tests/ui/issues/issue-37534.rs b/tests/ui/issues/issue-37534.rs index 40f7186db098e..dff89d3888d0c 100644 --- a/tests/ui/issues/issue-37534.rs +++ b/tests/ui/issues/issue-37534.rs @@ -1,6 +1,5 @@ struct Foo {} //~^ ERROR expected trait, found derive macro `Hash` -//~^^ ERROR parameter `T` is never used -//~^^^ WARN relaxing a default bound only does something for `?Sized` +//~| WARN relaxing a default bound only does something for `?Sized` fn main() {} diff --git a/tests/ui/issues/issue-37534.stderr b/tests/ui/issues/issue-37534.stderr index a687e733d3dae..8747bd5ac6fad 100644 --- a/tests/ui/issues/issue-37534.stderr +++ b/tests/ui/issues/issue-37534.stderr @@ -15,15 +15,6 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr LL | struct Foo {} | ^^^^^ -error[E0392]: type parameter `T` is never used - --> $DIR/issue-37534.rs:1:12 - | -LL | struct Foo {} - | ^ unused type parameter - | - = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData` - -error: aborting due to 2 previous errors; 1 warning emitted +error: aborting due to 1 previous error; 1 warning emitted -Some errors have detailed explanations: E0392, E0404. -For more information about an error, try `rustc --explain E0392`. +For more information about this error, try `rustc --explain E0404`. diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.rs b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs new file mode 100644 index 0000000000000..dfa8e9886b6b8 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs @@ -0,0 +1,4 @@ +fn uwu>() {} +//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr new file mode 100644 index 0000000000000..3297eb6279fab --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr @@ -0,0 +1,11 @@ +error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied + --> $DIR/maybe-bound-generics-deny.rs:1:12 + | +LL | fn uwu>() {} + | ^^^^^----- help: remove the unnecessary generics + | | + | expected 0 generic arguments + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs new file mode 100644 index 0000000000000..2cb63f25d063d --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs @@ -0,0 +1,7 @@ +trait Trait {} + +fn test::Trait>() {} +//~^ ERROR type arguments are not allowed on this type +//~| WARN relaxing a default bound only does something for `?Sized` + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr new file mode 100644 index 0000000000000..701e493f5a527 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr @@ -0,0 +1,17 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-has-path-args.rs:3:12 + | +LL | fn test::Trait>() {} + | ^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type arguments are not allowed on this type + --> $DIR/maybe-bound-has-path-args.rs:3:20 + | +LL | fn test::Trait>() {} + | ---- ^^^ type argument not allowed + | | + | not allowed on this type + +error: aborting due to 1 previous error; 1 warning emitted + +For more information about this error, try `rustc --explain E0109`. From 06a49b609f763cacf76a4fcdd3ae8f142e0b8b2d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 31 Oct 2024 00:09:34 +0000 Subject: [PATCH 04/17] Validate associated type bounds on ? --- .../src/hir_ty_lowering/mod.rs | 38 ++++++++++++------- .../ui/trait-bounds/maybe-bound-with-assoc.rs | 12 ++++++ .../maybe-bound-with-assoc.stderr | 21 ++++++++++ 3 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 tests/ui/trait-bounds/maybe-bound-with-assoc.rs create mode 100644 tests/ui/trait-bounds/maybe-bound-with-assoc.stderr diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 9b0d21bc00943..738b31331284f 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -681,11 +681,32 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { Some(self_ty), ); + let tcx = self.tcx(); + let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); + debug!(?bound_vars); + + let poly_trait_ref = ty::Binder::bind_with_vars( + ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args), + bound_vars, + ); + let polarity = match polarity { rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive, rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative, rustc_ast::BoundPolarity::Maybe(_) => { - // No-op. + // Validate associated type at least. We may want to reject these + // outright in the future... + for constraint in trait_segment.args().constraints { + let _ = self.lower_assoc_item_constraint( + trait_ref.hir_ref_id, + poly_trait_ref, + constraint, + &mut Default::default(), + &mut Default::default(), + constraint.span, + predicate_filter, + ); + } return arg_count; } }; @@ -699,15 +720,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { }); } - let tcx = self.tcx(); - let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id); - debug!(?bound_vars); - - let poly_trait_ref = ty::Binder::bind_with_vars( - ty::TraitRef::new_from_args(tcx, trait_def_id, generic_args), - bound_vars, - ); - match predicate_filter { PredicateFilter::All | PredicateFilter::SelfOnly @@ -758,11 +770,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { // since we should have emitted an error for them earlier, and they // would not be well-formed! if polarity != ty::PredicatePolarity::Positive { - assert!( - self.dcx().has_errors().is_some(), + self.dcx().span_delayed_bug( + constraint.span, "negative trait bounds should not have assoc item constraints", ); - continue; + break; } // Specify type to assert that error was already reported in `Err` case. diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.rs b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs new file mode 100644 index 0000000000000..b6b2551e4638e --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs @@ -0,0 +1,12 @@ +trait HasAssoc { + type Assoc; +} +fn hasassoc>() {} +//~^ WARN relaxing a default bound + +trait NoAssoc {} +fn noassoc>() {} +//~^ WARN relaxing a default bound +//~| ERROR associated type `Missing` not found for `NoAssoc` + +fn main() {} diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr new file mode 100644 index 0000000000000..91d78e59cd5a7 --- /dev/null +++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr @@ -0,0 +1,21 @@ +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:4:16 + | +LL | fn hasassoc>() {} + | ^^^^^^^^^^^^^^^^^^^^^ + +warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default + --> $DIR/maybe-bound-with-assoc.rs:8:15 + | +LL | fn noassoc>() {} + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0220]: associated type `Missing` not found for `NoAssoc` + --> $DIR/maybe-bound-with-assoc.rs:8:24 + | +LL | fn noassoc>() {} + | ^^^^^^^ associated type `Missing` not found + +error: aborting due to 1 previous error; 2 warnings emitted + +For more information about this error, try `rustc --explain E0220`. From eca17022ef267f9ed87ba7d22755a1bfe0082e80 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 30 Oct 2024 20:37:51 -0700 Subject: [PATCH 05/17] compiler: Lift `rustc_target::spec::abi::Abi` to `rustc_abi::ExternAbi` --- Cargo.lock | 2 ++ compiler/rustc_abi/Cargo.toml | 4 ++++ .../src/spec/abi => rustc_abi/src/extern_abi}/mod.rs | 4 +++- .../src/spec/abi => rustc_abi/src/extern_abi}/tests.rs | 0 compiler/rustc_abi/src/lib.rs | 8 ++++++++ compiler/rustc_target/src/spec/mod.rs | 8 +++++++- 6 files changed, 24 insertions(+), 2 deletions(-) rename compiler/{rustc_target/src/spec/abi => rustc_abi/src/extern_abi}/mod.rs (99%) rename compiler/{rustc_target/src/spec/abi => rustc_abi/src/extern_abi}/tests.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index fc16ccf0a6793..e2bd466a9d658 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3204,9 +3204,11 @@ dependencies = [ "rand", "rand_xoshiro", "rustc_data_structures", + "rustc_feature", "rustc_index", "rustc_macros", "rustc_serialize", + "rustc_span", "tracing", ] diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml index 7448f066d0ac1..3acd25e546114 100644 --- a/compiler/rustc_abi/Cargo.toml +++ b/compiler/rustc_abi/Cargo.toml @@ -9,9 +9,11 @@ bitflags = "2.4.1" rand = { version = "0.8.4", default-features = false, optional = true } rand_xoshiro = { version = "0.6.0", optional = true } rustc_data_structures = { path = "../rustc_data_structures", optional = true } +rustc_feature = { path = "../rustc_feature", optional = true } rustc_index = { path = "../rustc_index", default-features = false } rustc_macros = { path = "../rustc_macros", optional = true } rustc_serialize = { path = "../rustc_serialize", optional = true } +rustc_span = { path = "../rustc_span", optional = true } tracing = "0.1" # tidy-alphabetical-end @@ -22,8 +24,10 @@ default = ["nightly", "randomize"] # without depending on rustc_data_structures, rustc_macros and rustc_serialize nightly = [ "dep:rustc_data_structures", + "dep:rustc_feature", "dep:rustc_macros", "dep:rustc_serialize", + "dep:rustc_span", "rustc_index/nightly", ] randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"] diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_abi/src/extern_abi/mod.rs similarity index 99% rename from compiler/rustc_target/src/spec/abi/mod.rs rename to compiler/rustc_abi/src/extern_abi/mod.rs index c2095155afafe..f7e41280131fa 100644 --- a/compiler/rustc_target/src/spec/abi/mod.rs +++ b/compiler/rustc_abi/src/extern_abi/mod.rs @@ -7,9 +7,11 @@ use rustc_span::{Span, Symbol}; #[cfg(test)] mod tests; +use ExternAbi as Abi; + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)] #[derive(HashStable_Generic, Encodable, Decodable)] -pub enum Abi { +pub enum ExternAbi { // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the // hashing tests. These are used in many places, so giving them stable values reduces test // churn. The specific values are meaningless. diff --git a/compiler/rustc_target/src/spec/abi/tests.rs b/compiler/rustc_abi/src/extern_abi/tests.rs similarity index 100% rename from compiler/rustc_target/src/spec/abi/tests.rs rename to compiler/rustc_abi/src/extern_abi/tests.rs diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs index fac1122c4dfc7..ec758785173b6 100644 --- a/compiler/rustc_abi/src/lib.rs +++ b/compiler/rustc_abi/src/lib.rs @@ -1,6 +1,7 @@ // tidy-alphabetical-start #![cfg_attr(feature = "nightly", allow(internal_features))] #![cfg_attr(feature = "nightly", doc(rust_logo))] +#![cfg_attr(feature = "nightly", feature(assert_matches))] #![cfg_attr(feature = "nightly", feature(rustc_attrs))] #![cfg_attr(feature = "nightly", feature(rustdoc_internals))] #![cfg_attr(feature = "nightly", feature(step_trait))] @@ -28,8 +29,15 @@ mod layout; #[cfg(test)] mod tests; +#[cfg(feature = "nightly")] +mod extern_abi; + pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind}; #[cfg(feature = "nightly")] +pub use extern_abi::{ + AbiDisabled, AbiUnsupported, ExternAbi, all_names, enabled_names, is_enabled, is_stable, lookup, +}; +#[cfg(feature = "nightly")] pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx}; pub use layout::{LayoutCalculator, LayoutCalculatorError}; diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index f4cbe47e0f352..3e7b42d3d1c13 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -55,9 +55,15 @@ use crate::json::{Json, ToJson}; use crate::spec::abi::Abi; use crate::spec::crt_objects::CrtObjects; -pub mod abi; pub mod crt_objects; +pub mod abi { + pub use rustc_abi::{ + AbiDisabled, AbiUnsupported, ExternAbi as Abi, all_names, enabled_names, is_enabled, + is_stable, lookup, + }; +} + mod base; pub use base::apple::{ deployment_target_for_target as current_apple_deployment_target, From 8a0e64078e79a58d8cae104fa8429f246ae5e68f Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 30 Oct 2024 21:57:40 -0700 Subject: [PATCH 06/17] compiler: Switch to rustc_abi in hir_pretty, lint_defs, and mir_build Completely abandon usage of rustc_target in these crates, as they need no special knowledge of rustc's target tuples. --- Cargo.lock | 6 +++--- compiler/rustc_hir_pretty/Cargo.toml | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 6 +++--- compiler/rustc_lint_defs/Cargo.toml | 2 +- compiler/rustc_lint_defs/src/lib.rs | 4 ++-- compiler/rustc_mir_build/Cargo.toml | 3 ++- .../rustc_mir_build/src/build/custom/parse/instruction.rs | 2 +- compiler/rustc_mir_build/src/build/expr/as_constant.rs | 2 +- compiler/rustc_mir_build/src/build/expr/as_place.rs | 2 +- compiler/rustc_mir_build/src/build/expr/as_rvalue.rs | 2 +- compiler/rustc_mir_build/src/build/matches/mod.rs | 2 +- compiler/rustc_mir_build/src/build/mod.rs | 7 +++---- compiler/rustc_mir_build/src/thir/cx/expr.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs | 2 +- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 2 +- 15 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e2bd466a9d658..0f65cc696abbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3751,11 +3751,11 @@ dependencies = [ name = "rustc_hir_pretty" version = "0.0.0" dependencies = [ + "rustc_abi", "rustc_ast", "rustc_ast_pretty", "rustc_hir", "rustc_span", - "rustc_target", ] [[package]] @@ -3940,6 +3940,7 @@ dependencies = [ name = "rustc_lint_defs" version = "0.0.0" dependencies = [ + "rustc_abi", "rustc_ast", "rustc_data_structures", "rustc_error_messages", @@ -3947,7 +3948,6 @@ dependencies = [ "rustc_macros", "rustc_serialize", "rustc_span", - "rustc_target", "serde", ] @@ -4056,6 +4056,7 @@ version = "0.0.0" dependencies = [ "either", "itertools", + "rustc_abi", "rustc_apfloat", "rustc_arena", "rustc_ast", @@ -4071,7 +4072,6 @@ dependencies = [ "rustc_pattern_analysis", "rustc_session", "rustc_span", - "rustc_target", "rustc_trait_selection", "tracing", ] diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml index aacf41b6eb737..9af1fb8279e9f 100644 --- a/compiler/rustc_hir_pretty/Cargo.toml +++ b/compiler/rustc_hir_pretty/Cargo.toml @@ -5,9 +5,9 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_ast_pretty = { path = "../rustc_ast_pretty" } rustc_hir = { path = "../rustc_hir" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } # tidy-alphabetical-end diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 2073f2868b4fc..0a3aa8fec9005 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -9,6 +9,7 @@ use std::cell::Cell; use std::vec; +use rustc_abi::ExternAbi; use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; @@ -20,7 +21,6 @@ use rustc_hir::{ use rustc_span::FileName; use rustc_span::source_map::SourceMap; use rustc_span::symbol::{Ident, Symbol, kw}; -use rustc_target::spec::abi::Abi; use {rustc_ast as ast, rustc_hir as hir}; pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String { @@ -2240,7 +2240,7 @@ impl<'a> State<'a> { fn print_ty_fn( &mut self, - abi: Abi, + abi: ExternAbi, safety: hir::Safety, decl: &hir::FnDecl<'_>, name: Option, @@ -2276,7 +2276,7 @@ impl<'a> State<'a> { self.print_safety(header.safety); - if header.abi != Abi::Rust { + if header.abi != ExternAbi::Rust { self.word_nbsp("extern"); self.word_nbsp(header.abi.to_string()); } diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml index eb2a184ef84b1..450885e71647f 100644 --- a/compiler/rustc_lint_defs/Cargo.toml +++ b/compiler/rustc_lint_defs/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] # tidy-alphabetical-start +rustc_abi = { path = "../rustc_abi" } rustc_ast = { path = "../rustc_ast" } rustc_data_structures = { path = "../rustc_data_structures" } rustc_error_messages = { path = "../rustc_error_messages" } @@ -12,6 +13,5 @@ rustc_hir = { path = "../rustc_hir" } rustc_macros = { path = "../rustc_macros" } rustc_serialize = { path = "../rustc_serialize" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } serde = { version = "1.0.125", features = ["derive"] } # tidy-alphabetical-end diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 601784f973231..0caf6ef3a6d7a 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -2,6 +2,7 @@ #![warn(unreachable_pub)] // tidy-alphabetical-end +use rustc_abi::ExternAbi; use rustc_ast::node_id::NodeId; use rustc_ast::{AttrId, Attribute}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; @@ -15,7 +16,6 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic}; pub use rustc_span::edition::Edition; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent}; use rustc_span::{Span, Symbol, sym}; -use rustc_target::spec::abi::Abi; use serde::{Deserialize, Serialize}; pub use self::Level::*; @@ -602,7 +602,7 @@ pub enum BuiltinLintDiag { path: String, since_kind: DeprecatedSinceKind, }, - MissingAbi(Span, Abi), + MissingAbi(Span, ExternAbi), UnusedDocComment(Span), UnusedBuiltinAttribute { attr_name: Symbol, diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml index 529e9cc271136..119047227431d 100644 --- a/compiler/rustc_mir_build/Cargo.toml +++ b/compiler/rustc_mir_build/Cargo.toml @@ -7,6 +7,8 @@ edition = "2021" # tidy-alphabetical-start either = "1.5.0" itertools = "0.12" + +rustc_abi = { path = "../rustc_abi" } rustc_apfloat = "0.2.0" rustc_arena = { path = "../rustc_arena" } rustc_ast = { path = "../rustc_ast" } @@ -22,7 +24,6 @@ rustc_middle = { path = "../rustc_middle" } rustc_pattern_analysis = { path = "../rustc_pattern_analysis" } rustc_session = { path = "../rustc_session" } rustc_span = { path = "../rustc_span" } -rustc_target = { path = "../rustc_target" } rustc_trait_selection = { path = "../rustc_trait_selection" } tracing = "0.1" # tidy-alphabetical-end diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs index 9e3af89105294..07964e304b9ed 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -1,3 +1,4 @@ +use rustc_abi::{FieldIdx, VariantIdx}; use rustc_middle::mir::interpret::Scalar; use rustc_middle::mir::tcx::PlaceTy; use rustc_middle::mir::*; @@ -6,7 +7,6 @@ use rustc_middle::ty; use rustc_middle::ty::cast::mir_cast_kind; use rustc_span::Span; use rustc_span::source_map::Spanned; -use rustc_target::abi::{FieldIdx, VariantIdx}; use super::{PResult, ParseCtxt, parse_by_kind}; use crate::build::custom::ParseError; diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs index ae164cf760569..3f2e3b956fc63 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -1,5 +1,6 @@ //! See docs in build/expr/mod.rs +use rustc_abi::Size; use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::mir::interpret::{ @@ -11,7 +12,6 @@ use rustc_middle::ty::{ self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex, }; use rustc_middle::{bug, mir, span_bug}; -use rustc_target::abi::Size; use tracing::{instrument, trace}; use crate::build::{Builder, parse_float_into_constval}; diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs index c7298e3ddfa90..9f6e0735b4822 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_place.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs @@ -3,6 +3,7 @@ use std::assert_matches::assert_matches; use std::iter; +use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; use rustc_hir::def_id::LocalDefId; use rustc_middle::hir::place::{Projection as HirProjection, ProjectionKind as HirProjectionKind}; use rustc_middle::middle::region; @@ -12,7 +13,6 @@ use rustc_middle::thir::*; use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance}; use rustc_middle::{bug, span_bug}; use rustc_span::Span; -use rustc_target::abi::{FIRST_VARIANT, FieldIdx, VariantIdx}; use tracing::{debug, instrument, trace}; use crate::build::ForGuard::{OutsideGuard, RefWithinGuard}; diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index 2357dd7349057..1985dd3fca0f6 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -1,5 +1,6 @@ //! See docs in `build/expr/mod.rs`. +use rustc_abi::{BackendRepr, FieldIdx, Primitive}; use rustc_hir::lang_items::LangItem; use rustc_index::{Idx, IndexVec}; use rustc_middle::bug; @@ -13,7 +14,6 @@ use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, Ty, UpvarArgs}; use rustc_span::source_map::Spanned; use rustc_span::{DUMMY_SP, Span}; -use rustc_target::abi::{BackendRepr, FieldIdx, Primitive}; use tracing::debug; use crate::build::expr::as_place::PlaceBase; diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs index 51ead57020556..a62d4e9d87373 100644 --- a/compiler/rustc_mir_build/src/build/matches/mod.rs +++ b/compiler/rustc_mir_build/src/build/matches/mod.rs @@ -5,6 +5,7 @@ //! This also includes code for pattern bindings in `let` statements and //! function parameters. +use rustc_abi::VariantIdx; use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir::{BindingMode, ByRef}; @@ -15,7 +16,6 @@ use rustc_middle::thir::{self, *}; use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty}; use rustc_span::symbol::Symbol; use rustc_span::{BytePos, Pos, Span}; -use rustc_target::abi::VariantIdx; use tracing::{debug, instrument}; use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard}; diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index e15ea4d8d8be2..1f853f6e1c302 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use rustc_abi::{ExternAbi, FieldIdx}; use rustc_apfloat::Float; use rustc_apfloat::ieee::{Double, Half, Quad, Single}; use rustc_ast::attr; @@ -20,8 +21,6 @@ use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt, TypingMode use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use rustc_span::{Span, Symbol}; -use rustc_target::abi::FieldIdx; -use rustc_target::spec::abi::Abi; use super::lints; use crate::build::expr::as_place::PlaceBuilder; @@ -467,7 +466,7 @@ fn construct_fn<'tcx>( if let DefKind::Closure = tcx.def_kind(fn_def) { // HACK(eddyb) Avoid having RustCall on closures, // as it adds unnecessary (and wrong) auto-tupling. - abi = Abi::Rust; + abi = ExternAbi::Rust; } let arguments = &thir.params; @@ -540,7 +539,7 @@ fn construct_fn<'tcx>( let mut body = builder.finish(); - body.spread_arg = if abi == Abi::RustCall { + body.spread_arg = if abi == ExternAbi::RustCall { // RustCall pseudo-ABI untuples the last argument. Some(Local::new(arguments.len())) } else { diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs index d20e5fcf4ec6d..793ef9c4556fb 100644 --- a/compiler/rustc_mir_build/src/thir/cx/expr.rs +++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs @@ -1,4 +1,5 @@ use itertools::Itertools; +use rustc_abi::{FIRST_VARIANT, FieldIdx}; use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; @@ -18,7 +19,6 @@ use rustc_middle::ty::{ }; use rustc_middle::{bug, span_bug}; use rustc_span::{Span, sym}; -use rustc_target::abi::{FIRST_VARIANT, FieldIdx}; use tracing::{debug, info, instrument, trace}; use crate::errors; diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index c89f526aa1758..983853d2de186 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -1,4 +1,5 @@ use either::Either; +use rustc_abi::{FieldIdx, VariantIdx}; use rustc_apfloat::Float; use rustc_hir as hir; use rustc_index::Idx; @@ -9,7 +10,6 @@ use rustc_middle::mir::interpret::ErrorHandled; use rustc_middle::thir::{FieldPat, Pat, PatKind}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, ValTree}; use rustc_span::Span; -use rustc_target::abi::{FieldIdx, VariantIdx}; use rustc_trait_selection::traits::ObligationCause; use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt; use tracing::{debug, instrument, trace}; diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 56e5156a91fc0..ec852add94db7 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -5,6 +5,7 @@ mod const_to_pat; use std::cmp::Ordering; +use rustc_abi::{FieldIdx, Integer}; use rustc_errors::codes::*; use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::pat_util::EnumerateAndAdjustIterator; @@ -20,7 +21,6 @@ use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisita use rustc_middle::{bug, span_bug}; use rustc_span::def_id::LocalDefId; use rustc_span::{ErrorGuaranteed, Span}; -use rustc_target::abi::{FieldIdx, Integer}; use tracing::{debug, instrument}; pub(crate) use self::check_match::check_match; From cb26fa07bbb3e7c200c5511b3d010c4208a19a18 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 30 Oct 2024 13:12:08 +0100 Subject: [PATCH 07/17] Improve the missing_abi lint. --- compiler/rustc_ast/src/ast.rs | 2 ++ compiler/rustc_ast/src/mut_visit.rs | 2 +- compiler/rustc_ast/src/visit.rs | 2 +- compiler/rustc_ast_passes/src/ast_validation.rs | 13 ++++++------- compiler/rustc_lint/messages.ftl | 2 +- compiler/rustc_lint/src/lints.rs | 4 +--- compiler/rustc_parse/src/parser/item.rs | 2 ++ 7 files changed, 14 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs index 8e4f4c8e71a2e..ec6ca70ae0a4b 100644 --- a/compiler/rustc_ast/src/ast.rs +++ b/compiler/rustc_ast/src/ast.rs @@ -2810,6 +2810,8 @@ pub struct ModSpans { /// E.g., `extern { .. }` or `extern "C" { .. }`. #[derive(Clone, Encodable, Decodable, Debug)] pub struct ForeignMod { + /// Span of the `extern` keyword. + pub extern_span: Span, /// `unsafe` keyword accepted syntactically for macro DSLs, but not /// semantically by Rust. pub safety: Safety, diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs index 2afbd979c3023..44bb44cb7288e 100644 --- a/compiler/rustc_ast/src/mut_visit.rs +++ b/compiler/rustc_ast/src/mut_visit.rs @@ -525,7 +525,7 @@ pub fn walk_ty(vis: &mut T, ty: &mut P) { } fn walk_foreign_mod(vis: &mut T, foreign_mod: &mut ForeignMod) { - let ForeignMod { safety, abi: _, items } = foreign_mod; + let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod; visit_safety(vis, safety); items.flat_map_in_place(|item| vis.flat_map_foreign_item(item)); } diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs index eb71ec5f4ec93..2f8115441de9e 100644 --- a/compiler/rustc_ast/src/visit.rs +++ b/compiler/rustc_ast/src/visit.rs @@ -366,7 +366,7 @@ impl WalkItemKind for ItemKind { } ModKind::Unloaded => {} }, - ItemKind::ForeignMod(ForeignMod { safety: _, abi: _, items }) => { + ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => { walk_list!(visitor, visit_foreign_item, items); } ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)), diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 0a4f86d4822f7..dee48586f34cf 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -677,9 +677,8 @@ impl<'a> AstValidator<'a> { Self::check_decl_no_pat(&bfty.decl, |span, _, _| { self.dcx().emit_err(errors::PatternFnPointer { span }); }); - if let Extern::Implicit(_) = bfty.ext { - let sig_span = self.sess.source_map().next_point(ty.span.shrink_to_lo()); - self.maybe_lint_missing_abi(sig_span, ty.id); + if let Extern::Implicit(extern_span) = bfty.ext { + self.maybe_lint_missing_abi(extern_span, ty.id); } } TyKind::TraitObject(bounds, ..) => { @@ -953,7 +952,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { walk_list!(self, visit_attribute, &item.attrs); return; // Avoid visiting again. } - ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => { + ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => { self.with_in_extern_mod(*safety, |this| { let old_item = mem::replace(&mut this.extern_mod, Some(item.span)); this.visibility_not_permitted( @@ -977,7 +976,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } if abi.is_none() { - this.maybe_lint_missing_abi(item.span, item.id); + this.maybe_lint_missing_abi(*extern_span, item.id); } visit::walk_item(this, item); this.extern_mod = old_item; @@ -1350,13 +1349,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> { if let FnKind::Fn( _, _, - FnSig { span: sig_span, header: FnHeader { ext: Extern::Implicit(_), .. }, .. }, + FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. }, _, _, _, ) = fk { - self.maybe_lint_missing_abi(*sig_span, id); + self.maybe_lint_missing_abi(*extern_span, id); } // Functions without bodies cannot have patterns. diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 3fa43296dfcac..9187f6caad43c 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -268,7 +268,7 @@ lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edi lint_extern_without_abi = extern declarations without an explicit ABI are deprecated .label = ABI should be specified here - .help = the default ABI is {$default_abi} + .suggestion = explicitly specify the {$default_abi} ABI lint_for_loops_over_fallibles = for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs index 000f4b697bd68..38e52570e53e6 100644 --- a/compiler/rustc_lint/src/lints.rs +++ b/compiler/rustc_lint/src/lints.rs @@ -2738,11 +2738,9 @@ pub(crate) struct PatternsInFnsWithoutBodySub { #[derive(LintDiagnostic)] #[diag(lint_extern_without_abi)] -#[help] pub(crate) struct MissingAbi { - #[label] + #[suggestion(code = "extern \"{default_abi}\"", applicability = "machine-applicable")] pub span: Span, - pub default_abi: &'static str, } diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 36733726564fb..6b4e2d0f4e2f5 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -1194,6 +1194,7 @@ impl<'a> Parser<'a> { attrs: &mut AttrVec, mut safety: Safety, ) -> PResult<'a, ItemInfo> { + let extern_span = self.prev_token.uninterpolated_span(); let abi = self.parse_abi(); // ABI? // FIXME: This recovery should be tested better. if safety == Safety::Default @@ -1205,6 +1206,7 @@ impl<'a> Parser<'a> { let _ = self.eat_keyword(kw::Unsafe); } let module = ast::ForeignMod { + extern_span, safety, abi, items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?, From a433ea2518e18f3beda9bfdd11dc104e40eaa9ac Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 30 Oct 2024 13:41:26 +0100 Subject: [PATCH 08/17] Update tests. --- tests/ui/lint/cli-lint-override.forbid_warn.stderr | 3 +-- tests/ui/lint/cli-lint-override.force_warn_deny.stderr | 3 +-- tests/ui/lint/cli-lint-override.warn_deny.stderr | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/ui/lint/cli-lint-override.forbid_warn.stderr b/tests/ui/lint/cli-lint-override.forbid_warn.stderr index d8c75c33b0c56..169be997b48c6 100644 --- a/tests/ui/lint/cli-lint-override.forbid_warn.stderr +++ b/tests/ui/lint/cli-lint-override.forbid_warn.stderr @@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} - | ^^^^^^^^^^^^^^^ ABI should be specified here + | ^^^^^^ help: explicitly specify the C ABI: `extern "C"` | - = help: the default ABI is C = note: requested on the command line with `-F missing-abi` error: aborting due to 1 previous error diff --git a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr index 779c24c93f245..574f2ca66a420 100644 --- a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr +++ b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr @@ -2,9 +2,8 @@ warning: extern declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} - | ^^^^^^^^^^^^^^^ ABI should be specified here + | ^^^^^^ help: explicitly specify the C ABI: `extern "C"` | - = help: the default ABI is C = note: requested on the command line with `--force-warn missing-abi` warning: 1 warning emitted diff --git a/tests/ui/lint/cli-lint-override.warn_deny.stderr b/tests/ui/lint/cli-lint-override.warn_deny.stderr index 1ba42e9ce3234..bfec37ada95e5 100644 --- a/tests/ui/lint/cli-lint-override.warn_deny.stderr +++ b/tests/ui/lint/cli-lint-override.warn_deny.stderr @@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated --> $DIR/cli-lint-override.rs:12:1 | LL | extern fn foo() {} - | ^^^^^^^^^^^^^^^ ABI should be specified here + | ^^^^^^ help: explicitly specify the C ABI: `extern "C"` | - = help: the default ABI is C = note: requested on the command line with `-D missing-abi` error: aborting due to 1 previous error From 84295b917d9c29bb1d1cae9b24cf68d6b0d47d54 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 31 Oct 2024 12:06:19 +0100 Subject: [PATCH 09/17] traits::project: yeet `ParamEnv::reveal` --- .../src/traits/project.rs | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index a75c07c2e8c6e..aab854e9caf91 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -16,7 +16,7 @@ use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedD use rustc_middle::ty::fast_reject::DeepRejectCtxt; use rustc_middle::ty::fold::TypeFoldable; use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt}; -use rustc_middle::ty::{self, Term, Ty, TyCtxt, Upcast}; +use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::sym; use tracing::{debug, instrument}; @@ -975,18 +975,21 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( // and the obligation is monomorphic, otherwise passes such as // transmute checking and polymorphic MIR optimizations could // get a result which isn't correct for all monomorphizations. - if obligation.param_env.reveal() == Reveal::All { - // NOTE(eddyb) inference variables can resolve to parameters, so - // assume `poly_trait_ref` isn't monomorphic, if it contains any. - let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref); - !poly_trait_ref.still_further_specializable() - } else { - debug!( - assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), - ?obligation.predicate, - "assemble_candidates_from_impls: not eligible due to default", - ); - false + match selcx.infcx.typing_mode(obligation.param_env) { + TypingMode::Coherence | TypingMode::Analysis { .. } => { + debug!( + assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id), + ?obligation.predicate, + "assemble_candidates_from_impls: not eligible due to default", + ); + false + } + TypingMode::PostAnalysis => { + // NOTE(eddyb) inference variables can resolve to parameters, so + // assume `poly_trait_ref` isn't monomorphic, if it contains any. + let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref); + !poly_trait_ref.still_further_specializable() + } } } } From aab149b58ca47b19a8e1e1673b9fbc367f984c59 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 31 Oct 2024 12:22:05 +0100 Subject: [PATCH 10/17] `ConstCx` stop using `ParamEnv::reveal` --- .../src/check_consts/check.rs | 4 ++-- .../rustc_const_eval/src/check_consts/mod.rs | 7 ------ .../rustc_const_eval/src/check_consts/ops.rs | 4 ++-- compiler/rustc_middle/src/mir/syntax.rs | 23 ++++++++++++++----- compiler/rustc_mir_transform/src/validate.rs | 12 ++++------ .../clippy_utils/src/qualify_min_const_fn.rs | 4 ++-- 6 files changed, 27 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 5210241d5e49e..b1098c4f980df 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -16,7 +16,7 @@ use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::*; use rustc_middle::span_bug; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt, TypingMode}; +use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt}; use rustc_mir_dataflow::Analysis; use rustc_mir_dataflow::impls::MaybeStorageLive; use rustc_mir_dataflow::storage::always_storage_live_locals; @@ -589,7 +589,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish // which path expressions are getting called on and which path expressions are only used // as function pointers. This is required for correctness. - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); + let infcx = tcx.infer_ctxt().build(body.phase.typing_mode()); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args); diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs index 56da679184735..dcdaafaecc215 100644 --- a/compiler/rustc_const_eval/src/check_consts/mod.rs +++ b/compiler/rustc_const_eval/src/check_consts/mod.rs @@ -32,14 +32,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> { pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self { let def_id = body.source.def_id().expect_local(); let param_env = tcx.param_env(def_id); - Self::new_with_param_env(tcx, body, param_env) - } - pub fn new_with_param_env( - tcx: TyCtxt<'tcx>, - body: &'mir mir::Body<'tcx>, - param_env: ty::ParamEnv<'tcx>, - ) -> Self { let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local()); ConstCx { body, tcx, param_env, const_kind } } diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 3f977dc4b05aa..270a5880764a8 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -12,7 +12,7 @@ use rustc_middle::mir::CallSource; use rustc_middle::span_bug; use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths}; use rustc_middle::ty::{ - self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, TypingMode, + self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, suggest_constraining_type_param, }; use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind}; @@ -116,7 +116,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); + let infcx = tcx.infer_ctxt().build(body.phase.typing_mode()); let mut selcx = SelectionContext::new(&infcx); let implsrc = selcx.select(&obligation); diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index c610fac80f68f..10b12ee628290 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -19,9 +19,10 @@ use smallvec::SmallVec; use super::{BasicBlock, Const, Local, UserTypeProjection}; use crate::mir::coverage::CoverageKind; -use crate::traits::Reveal; use crate::ty::adjustment::PointerCoercion; -use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex}; +use crate::ty::{ + self, GenericArgsRef, List, Region, Ty, TyCtxt, TypingMode, UserTypeAnnotationIndex, +}; /// Represents the "flavors" of MIR. /// @@ -102,10 +103,20 @@ impl MirPhase { } } - pub fn reveal(&self) -> Reveal { - match *self { - MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing, - MirPhase::Runtime(_) => Reveal::All, + pub fn typing_mode<'tcx>(&self) -> TypingMode<'tcx> { + match self { + // FIXME(#132279): the MIR is quite clearly inside of a body, so we + // should instead reveal opaques defined by that body here. + MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(), + MirPhase::Runtime(_) => TypingMode::PostAnalysis, + } + } + + pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> { + match self.typing_mode() { + TypingMode::Coherence => unreachable!(), + TypingMode::Analysis { defining_opaque_types: _ } => tcx.param_env(body_def_id), + TypingMode::PostAnalysis => tcx.param_env_reveal_all_normalized(body_def_id), } } } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 77356723c466b..1fcbfdde4f738 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -5,14 +5,14 @@ use rustc_hir::LangItem; use rustc_index::IndexVec; use rustc_index::bit_set::BitSet; use rustc_infer::infer::TyCtxtInferExt; -use rustc_infer::traits::{Obligation, ObligationCause, Reveal}; +use rustc_infer::traits::{Obligation, ObligationCause}; use rustc_middle::mir::coverage::CoverageKind; use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::{ self, CoroutineArgsExt, InstanceKind, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt, - TypingMode, Variance, + Variance, }; use rustc_middle::{bug, span_bug}; use rustc_target::abi::{FIRST_VARIANT, Size}; @@ -50,11 +50,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator { } let def_id = body.source.def_id(); let mir_phase = self.mir_phase; - let param_env = match mir_phase.reveal() { - Reveal::UserFacing => tcx.param_env(def_id), - Reveal::All => tcx.param_env_reveal_all_normalized(def_id), - }; - + let param_env = mir_phase.param_env(tcx, def_id); let can_unwind = if mir_phase <= MirPhase::Runtime(RuntimePhase::Initial) { // In this case `AbortUnwindingCalls` haven't yet been executed. true @@ -606,7 +602,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env)); + let infcx = self.tcx.infer_ctxt().build(self.body.phase.typing_mode()); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( self.tcx, diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index dbadc8432f630..30c97a5751496 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -17,7 +17,7 @@ use rustc_middle::mir::{ }; use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause}; use rustc_middle::ty::adjustment::PointerCoercion; -use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt, TypingMode}; +use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt}; use rustc_span::Span; use rustc_span::symbol::sym; use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext}; @@ -420,7 +420,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx> TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]), ); - let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(obligation.param_env)); + let infcx = tcx.infer_ctxt().build(body.phase.typing_mode()); let mut selcx = SelectionContext::new(&infcx); let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { return false; From 563c473e8d23cc6ebbe501d30749ee4225efa1e6 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 31 Oct 2024 12:26:37 +0100 Subject: [PATCH 11/17] clippy: we've got a `LateContext` use it for `TypingMode` --- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index c618bfe4488c1..41785e161d0ce 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -362,7 +362,7 @@ fn is_normalizable_helper<'tcx>( } // prevent recursive loops, false-negative is better than endless loop leading to stack overflow cache.insert(ty, false); - let infcx = cx.tcx.infer_ctxt().build(TypingMode::from_param_env(param_env)); + let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode()); let cause = ObligationCause::dummy(); let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() { match ty.kind() { From 2cde638ac0b8f2fd1b7ad29606a1a406b276482a Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 31 Oct 2024 12:41:50 +0100 Subject: [PATCH 12/17] stop using `ParamEnv::reveal` while handling MIR --- .../src/check_consts/check.rs | 2 +- .../rustc_const_eval/src/check_consts/ops.rs | 2 +- .../src/interpret/eval_context.rs | 21 ++++++++++++--- .../rustc_const_eval/src/interpret/operand.rs | 5 +++- .../rustc_const_eval/src/interpret/place.rs | 10 +++++-- .../rustc_const_eval/src/interpret/stack.rs | 13 ++++----- .../src/util/compare_types.rs | 21 +++++---------- compiler/rustc_const_eval/src/util/mod.rs | 2 +- compiler/rustc_middle/src/mir/mod.rs | 11 +++++++- compiler/rustc_middle/src/mir/syntax.rs | 20 +++----------- compiler/rustc_mir_transform/src/inline.rs | 27 ++++++++++++++----- compiler/rustc_mir_transform/src/validate.rs | 17 ++++++++---- compiler/rustc_type_ir/src/infer_ctxt.rs | 7 +++++ .../clippy_utils/src/qualify_min_const_fn.rs | 2 +- 14 files changed, 100 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index b1098c4f980df..b6c227638a194 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -589,7 +589,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> { // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish // which path expressions are getting called on and which path expressions are only used // as function pointers. This is required for correctness. - let infcx = tcx.infer_ctxt().build(body.phase.typing_mode()); + let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx)); let ocx = ObligationCtxt::new_with_diagnostics(&infcx); let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args); diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs index 270a5880764a8..961a27ae9bada 100644 --- a/compiler/rustc_const_eval/src/check_consts/ops.rs +++ b/compiler/rustc_const_eval/src/check_consts/ops.rs @@ -116,7 +116,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { let obligation = Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref); - let infcx = tcx.infer_ctxt().build(body.phase.typing_mode()); + let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx)); let mut selcx = SelectionContext::new(&infcx); let implsrc = selcx.select(&obligation); diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d81368e9fcc39..9043bd3e28e7d 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -3,7 +3,7 @@ use rustc_errors::DiagCtxtHandle; use rustc_hir::def_id::DefId; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::infer::at::ToTrace; -use rustc_infer::traits::ObligationCause; +use rustc_infer::traits::{ObligationCause, Reveal}; use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; use rustc_middle::ty::layout::{ @@ -116,6 +116,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> { /// This test should be symmetric, as it is primarily about layout compatibility. pub(super) fn mir_assign_valid_types<'tcx>( tcx: TyCtxt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, src: TyAndLayout<'tcx>, dest: TyAndLayout<'tcx>, @@ -124,7 +125,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( // all normal lifetimes are erased, higher-ranked types with their // late-bound lifetimes are still around and can lead to type // differences. - if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) { + if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) { // Make sure the layout is equal, too -- just to be safe. Miri really // needs layout equality. For performance reason we skip this check when // the types are equal. Equal types *can* have different layouts when @@ -144,6 +145,7 @@ pub(super) fn mir_assign_valid_types<'tcx>( #[cfg_attr(not(debug_assertions), inline(always))] pub(super) fn from_known_layout<'tcx>( tcx: TyCtxtAt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, known_layout: Option>, compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>, @@ -153,7 +155,13 @@ pub(super) fn from_known_layout<'tcx>( Some(known_layout) => { if cfg!(debug_assertions) { let check_layout = compute()?; - if !mir_assign_valid_types(tcx.tcx, param_env, check_layout, known_layout) { + if !mir_assign_valid_types( + tcx.tcx, + typing_mode, + param_env, + check_layout, + known_layout, + ) { span_bug!( tcx.span, "expected type differs from actual type.\nexpected: {}\nactual: {}", @@ -203,6 +211,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { } } + pub fn typing_mode(&self) -> TypingMode<'tcx> { + debug_assert_eq!(self.param_env.reveal(), Reveal::All); + TypingMode::PostAnalysis + } + /// Returns the span of the currently executed statement/terminator. /// This is the span typically used for error reporting. #[inline(always)] @@ -327,7 +340,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return true; } // Slow path: spin up an inference context to check if these traits are sufficiently equal. - let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env)); + let infcx = self.tcx.infer_ctxt().build(self.typing_mode()); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy_with_span(self.cur_span()); // equate the two trait refs after normalization diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs index 43ae98e74b002..a130ae89bcb62 100644 --- a/compiler/rustc_const_eval/src/interpret/operand.rs +++ b/compiler/rustc_const_eval/src/interpret/operand.rs @@ -773,6 +773,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { )?; if !mir_assign_valid_types( *self.tcx, + self.typing_mode(), self.param_env, self.layout_of(normalized_place_ty)?, op.layout, @@ -832,7 +833,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { }) }; let layout = - from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty).into())?; + from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || { + self.layout_of(ty).into() + })?; let imm = match val_val { mir::ConstValue::Indirect { alloc_id, offset } => { // This is const data, no mutation allowed. diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 139a1db60e03f..cc8d1db6cfb8f 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -540,6 +540,7 @@ where )?; if !mir_assign_valid_types( *self.tcx, + self.typing_mode(), self.param_env, self.layout_of(normalized_place_ty)?, place.layout, @@ -870,8 +871,13 @@ where ) -> InterpResult<'tcx> { // We do NOT compare the types for equality, because well-typed code can // actually "transmute" `&mut T` to `&T` in an assignment without a cast. - let layout_compat = - mir_assign_valid_types(*self.tcx, self.param_env, src.layout(), dest.layout()); + let layout_compat = mir_assign_valid_types( + *self.tcx, + self.typing_mode(), + self.param_env, + src.layout(), + dest.layout(), + ); if !allow_transmute && !layout_compat { span_bug!( self.cur_span(), diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs index 3bc9f46aea066..50c0446b3cd85 100644 --- a/compiler/rustc_const_eval/src/interpret/stack.rs +++ b/compiler/rustc_const_eval/src/interpret/stack.rs @@ -596,12 +596,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { return interp_ok(layout); } - let layout = from_known_layout(self.tcx, self.param_env, layout, || { - let local_ty = frame.body.local_decls[local].ty; - let local_ty = - self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?; - self.layout_of(local_ty).into() - })?; + let layout = + from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || { + let local_ty = frame.body.local_decls[local].ty; + let local_ty = + self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?; + self.layout_of(local_ty).into() + })?; // Layouts of locals are requested a lot, so we cache them. state.layout.set(Some(layout)); diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs index 7af977bab4d66..0cf27d30c368c 100644 --- a/compiler/rustc_const_eval/src/util/compare_types.rs +++ b/compiler/rustc_const_eval/src/util/compare_types.rs @@ -8,24 +8,15 @@ use rustc_middle::traits::ObligationCause; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance}; use rustc_trait_selection::traits::ObligationCtxt; -/// Returns whether the two types are equal up to subtyping. -/// -/// This is used in case we don't know the expected subtyping direction -/// and still want to check whether anything is broken. -pub fn is_equal_up_to_subtyping<'tcx>( +/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. +pub fn sub_types<'tcx>( tcx: TyCtxt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, src: Ty<'tcx>, dest: Ty<'tcx>, ) -> bool { - // Fast path. - if src == dest { - return true; - } - - // Check for subtyping in either direction. - relate_types(tcx, param_env, Variance::Covariant, src, dest) - || relate_types(tcx, param_env, Variance::Covariant, dest, src) + relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest) } /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`. @@ -35,6 +26,7 @@ pub fn is_equal_up_to_subtyping<'tcx>( /// because we want to check for type equality. pub fn relate_types<'tcx>( tcx: TyCtxt<'tcx>, + typing_mode: TypingMode<'tcx>, param_env: ParamEnv<'tcx>, variance: Variance, src: Ty<'tcx>, @@ -45,8 +37,7 @@ pub fn relate_types<'tcx>( } let mut builder = tcx.infer_ctxt().ignoring_regions(); - // FIXME(#132279): This should eventually use the already defined hidden types. - let infcx = builder.build(TypingMode::from_param_env(param_env)); + let infcx = builder.build(typing_mode); let ocx = ObligationCtxt::new(&infcx); let cause = ObligationCause::dummy(); let src = ocx.normalize(&cause, param_env, src); diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs index 66a1addfb525e..25a9dbb2c1117 100644 --- a/compiler/rustc_const_eval/src/util/mod.rs +++ b/compiler/rustc_const_eval/src/util/mod.rs @@ -8,7 +8,7 @@ mod type_name; pub use self::alignment::{is_disaligned, is_within_packed}; pub use self::check_validity_requirement::check_validity_requirement; -pub use self::compare_types::{is_equal_up_to_subtyping, relate_types}; +pub use self::compare_types::{relate_types, sub_types}; pub use self::type_name::type_name; /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index cd148aef29ba8..978abab8b08d9 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable}; use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths}; use crate::ty::visit::TypeVisitableExt; use crate::ty::{ - self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, + self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode, UserTypeAnnotationIndex, }; @@ -452,6 +452,15 @@ impl<'tcx> Body<'tcx> { self.basic_blocks.as_mut() } + pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> { + match self.phase { + // FIXME(#132279): the MIR is quite clearly inside of a body, so we + // should instead reveal opaques defined by that body here. + MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(), + MirPhase::Runtime(_) => TypingMode::PostAnalysis, + } + } + #[inline] pub fn local_kind(&self, local: Local) -> LocalKind { let index = local.as_usize(); diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs index 10b12ee628290..85beb6ef1e79b 100644 --- a/compiler/rustc_middle/src/mir/syntax.rs +++ b/compiler/rustc_middle/src/mir/syntax.rs @@ -20,9 +20,7 @@ use smallvec::SmallVec; use super::{BasicBlock, Const, Local, UserTypeProjection}; use crate::mir::coverage::CoverageKind; use crate::ty::adjustment::PointerCoercion; -use crate::ty::{ - self, GenericArgsRef, List, Region, Ty, TyCtxt, TypingMode, UserTypeAnnotationIndex, -}; +use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex}; /// Represents the "flavors" of MIR. /// @@ -103,20 +101,10 @@ impl MirPhase { } } - pub fn typing_mode<'tcx>(&self) -> TypingMode<'tcx> { - match self { - // FIXME(#132279): the MIR is quite clearly inside of a body, so we - // should instead reveal opaques defined by that body here. - MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(), - MirPhase::Runtime(_) => TypingMode::PostAnalysis, - } - } - pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> { - match self.typing_mode() { - TypingMode::Coherence => unreachable!(), - TypingMode::Analysis { defining_opaque_types: _ } => tcx.param_env(body_def_id), - TypingMode::PostAnalysis => tcx.param_env_reveal_all_normalized(body_def_id), + match self { + MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id), + MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id), } } } diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 42d6bdf6cee76..404470db5c5bb 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -244,8 +244,13 @@ impl<'tcx> Inliner<'tcx> { // Normally, this shouldn't be required, but trait normalization failure can create a // validation ICE. let output_type = callee_body.return_ty(); - if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty) - { + if !util::sub_types( + self.tcx, + caller_body.typing_mode(self.tcx), + self.param_env, + output_type, + destination_ty, + ) { trace!(?output_type, ?destination_ty); return Err("failed to normalize return type"); } @@ -275,8 +280,13 @@ impl<'tcx> Inliner<'tcx> { self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; - if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) - { + if !util::sub_types( + self.tcx, + caller_body.typing_mode(self.tcx), + self.param_env, + input_type, + arg_ty, + ) { trace!(?arg_ty, ?input_type); return Err("failed to normalize tuple argument type"); } @@ -285,8 +295,13 @@ impl<'tcx> Inliner<'tcx> { for (arg, input) in args.iter().zip(callee_body.args_iter()) { let input_type = callee_body.local_decls[input].ty; let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx); - if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty) - { + if !util::sub_types( + self.tcx, + caller_body.typing_mode(self.tcx), + self.param_env, + input_type, + arg_ty, + ) { trace!(?arg_ty, ?input_type); return Err("failed to normalize argument type"); } diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs index 1fcbfdde4f738..8109a9b8ba0d1 100644 --- a/compiler/rustc_mir_transform/src/validate.rs +++ b/compiler/rustc_mir_transform/src/validate.rs @@ -20,7 +20,7 @@ use rustc_target::spec::abi::Abi; use rustc_trait_selection::traits::ObligationCtxt; use rustc_type_ir::Upcast; -use crate::util::{is_within_packed, relate_types}; +use crate::util::{self, is_within_packed}; #[derive(Copy, Clone, Debug, PartialEq, Eq)] enum EdgeKind { @@ -583,7 +583,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { Variance::Covariant }; - crate::util::relate_types(self.tcx, self.param_env, variance, src, dest) + crate::util::relate_types( + self.tcx, + self.body.typing_mode(self.tcx), + self.param_env, + variance, + src, + dest, + ) } /// Check that the given predicate definitely holds in the param-env of this MIR body. @@ -602,7 +609,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { return true; } - let infcx = self.tcx.infer_ctxt().build(self.body.phase.typing_mode()); + let infcx = self.tcx.infer_ctxt().build(self.body.typing_mode(self.tcx)); let ocx = ObligationCtxt::new(&infcx); ocx.register_obligation(Obligation::new( self.tcx, @@ -794,10 +801,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> { } } ProjectionElem::Subtype(ty) => { - if !relate_types( + if !util::sub_types( self.tcx, + self.body.typing_mode(self.tcx), self.param_env, - Variance::Covariant, ty, place_ref.ty(&self.body.local_decls, self.tcx).ty, ) { diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs index 22223e4a8900a..aadb64f45d77d 100644 --- a/compiler/rustc_type_ir/src/infer_ctxt.rs +++ b/compiler/rustc_type_ir/src/infer_ctxt.rs @@ -12,6 +12,13 @@ use crate::{self as ty, Interner}; /// The current typing mode of an inference context. We unfortunately have some /// slightly different typing rules depending on the current context. See the /// doc comment for each variant for how and why they are used. +/// +/// In most cases you can get the correct typing mode automically via: +/// - `mir::Body::typing_mode` +/// - `rustc_lint::LateContext::typing_mode` +/// +/// If neither of these functions are available, feel free to reach out to +/// t-types for help. #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)] #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))] pub enum TypingMode { diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 30c97a5751496..8f9f75d6824ad 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -420,7 +420,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx> TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]), ); - let infcx = tcx.infer_ctxt().build(body.phase.typing_mode()); + let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx)); let mut selcx = SelectionContext::new(&infcx); let Some(impl_src) = selcx.select(&obligation).ok().flatten() else { return false; From dc750665ae84cdedfbae4d5b3c69f4d20faa14dc Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 31 Oct 2024 13:05:27 +0100 Subject: [PATCH 13/17] normalization folders, yeet `ParamEnv::reveal` --- .../rustc_trait_selection/src/traits/mod.rs | 2 +- .../src/traits/normalize.rs | 33 +++++++++++-------- .../src/traits/query/normalize.rs | 20 ++++++----- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 1c84f2171bcac..436c0fabd2966 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -411,7 +411,7 @@ pub fn normalize_param_env_or_error<'tcx>( debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates); let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal()); - if !normalize::needs_normalization(&elaborated_env, unnormalized_env.reveal()) { + if !elaborated_env.has_aliases() { return elaborated_env; } diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs index 12e00ec79ac47..954dfe93387de 100644 --- a/compiler/rustc_trait_selection/src/traits/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/normalize.rs @@ -1,15 +1,16 @@ //! Deeply normalize types using the old trait solver. use rustc_data_structures::stack::ensure_sufficient_stack; -use rustc_infer::infer::InferOk; use rustc_infer::infer::at::At; +use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::traits::{ FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine, }; use rustc_macros::extension; -use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal}; +use rustc_middle::traits::{ObligationCause, ObligationCauseCode}; use rustc_middle::ty::{ self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt, + TypingMode, }; use tracing::{debug, instrument}; @@ -109,16 +110,19 @@ where } pub(super) fn needs_normalization<'tcx, T: TypeVisitable>>( + infcx: &InferCtxt<'tcx>, + param_env_for_debug_assertion: ty::ParamEnv<'tcx>, value: &T, - reveal: Reveal, ) -> bool { let mut flags = ty::TypeFlags::HAS_ALIAS; // Opaques are treated as rigid with `Reveal::UserFacing`, // so we can ignore those. - match reveal { - Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE), - Reveal::All => {} + match infcx.typing_mode(param_env_for_debug_assertion) { + TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { + flags.remove(ty::TypeFlags::HAS_TY_OPAQUE) + } + TypingMode::PostAnalysis => {} } value.has_type_flags(flags) @@ -154,7 +158,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> { "Normalizing {value:?} without wrapping in a `Binder`" ); - if !needs_normalization(&value, self.param_env.reveal()) { + if !needs_normalization(self.selcx.infcx, self.param_env, &value) { value } else { value.fold_with(self) @@ -178,7 +182,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx } fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> { - if !needs_normalization(&ty, self.param_env.reveal()) { + if !needs_normalization(self.selcx.infcx, self.param_env, &ty) { return ty; } @@ -213,10 +217,11 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.param_env.reveal() { - Reveal::UserFacing => ty.super_fold_with(self), - - Reveal::All => { + match self.selcx.infcx.typing_mode(self.param_env) { + TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { + ty.super_fold_with(self) + } + TypingMode::PostAnalysis => { let recursion_limit = self.cx().recursion_limit(); if !recursion_limit.value_within_limit(self.depth) { self.selcx.infcx.err_ctxt().report_overflow_error( @@ -403,7 +408,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> { let tcx = self.selcx.tcx(); if tcx.features().generic_const_exprs() - || !needs_normalization(&constant, self.param_env.reveal()) + || !needs_normalization(self.selcx.infcx, self.param_env, &constant) { constant } else { @@ -420,7 +425,7 @@ impl<'a, 'b, 'tcx> TypeFolder> for AssocTypeNormalizer<'a, 'b, 'tcx #[inline] fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> { - if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) { + if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) { p.super_fold_with(self) } else { p diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 01e6516302c2b..a8d701a750dd0 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -9,7 +9,7 @@ use rustc_macros::extension; pub use rustc_middle::traits::query::NormalizationResult; use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable}; use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt}; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor, TypingMode}; use rustc_span::DUMMY_SP; use tracing::{debug, info, instrument}; @@ -21,7 +21,7 @@ use crate::infer::canonical::OriginalQueryValues; use crate::infer::{InferCtxt, InferOk}; use crate::traits::normalize::needs_normalization; use crate::traits::{ - BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, Reveal, ScrubbedTraitError, + BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, ScrubbedTraitError, }; #[extension(pub trait QueryNormalizeExt<'tcx>)] @@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> { } } - if !needs_normalization(&value, self.param_env.reveal()) { + if !needs_normalization(self.infcx, self.param_env, &value) { return Ok(Normalized { value, obligations: PredicateObligations::new() }); } @@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { #[instrument(level = "debug", skip(self))] fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result, Self::Error> { - if !needs_normalization(&ty, self.param_env.reveal()) { + if !needs_normalization(self.infcx, self.param_env, &ty) { return Ok(ty); } @@ -215,10 +215,12 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { let res = match kind { ty::Opaque => { // Only normalize `impl Trait` outside of type inference, usually in codegen. - match self.param_env.reveal() { - Reveal::UserFacing => ty.try_super_fold_with(self)?, + match self.infcx.typing_mode(self.param_env) { + TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => { + ty.try_super_fold_with(self)? + } - Reveal::All => { + TypingMode::PostAnalysis => { let args = data.args.try_fold_with(self)?; let recursion_limit = self.cx().recursion_limit(); @@ -332,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { &mut self, constant: ty::Const<'tcx>, ) -> Result, Self::Error> { - if !needs_normalization(&constant, self.param_env.reveal()) { + if !needs_normalization(self.infcx, self.param_env, &constant) { return Ok(constant); } @@ -351,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder> for QueryNormalizer<'a, 'tcx> { &mut self, p: ty::Predicate<'tcx>, ) -> Result, Self::Error> { - if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) { + if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) { p.try_super_fold_with(self) } else { Ok(p) From 40f4b216ebe79541c0199fe04b4c65ff729cef18 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 29 Sep 2024 17:20:59 +0200 Subject: [PATCH 14/17] Document the difference between Clang's `-darwin` and `-macosx` targets --- src/doc/rustc/src/platform-support/apple-darwin.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/doc/rustc/src/platform-support/apple-darwin.md b/src/doc/rustc/src/platform-support/apple-darwin.md index c3a7b81f411e8..17ea225805b5c 100644 --- a/src/doc/rustc/src/platform-support/apple-darwin.md +++ b/src/doc/rustc/src/platform-support/apple-darwin.md @@ -52,5 +52,10 @@ Cross-compilation of these targets are supported using Clang, but may require Xcode or the macOS SDK (`MacOSX.sdk`) to be available to compile C code and to link. +The Clang target is suffixed with `-macosx`. Clang's `-darwin` target refers +to Darwin platforms in general (macOS/iOS/tvOS/watchOS/visionOS), and requires +the `-mmacosx-version-min=...`, `-miphoneos-version-min=...` or similar flags +to disambiguate. + The path to the SDK can be passed to `rustc` using the common `SDKROOT` environment variable. From 5b9d2848cbc34fcae600cb6f46babd25c8ecbf8e Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Mon, 28 Oct 2024 14:46:01 -0700 Subject: [PATCH 15/17] Bump Fuchsia --- src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh index 1a0b141e984bc..969389f92f7d7 100755 --- a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh +++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh @@ -35,7 +35,7 @@ PICK_REFS=() # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in # addition to versions of prebuilts. It should be bumped regularly by the # Fuchsia team – we aim for every 1-2 months. -INTEGRATION_SHA=1c5b42266fbfefb2337c6b2f0030a91bde15f9e9 +INTEGRATION_SHA=9f632bb7446d5a6af2998f1a0ebdb4b8ea2f4511 checkout=fuchsia jiri=.jiri_root/bin/jiri From abb05c0fd50fed5d5a59f8fcd9ec95532c070a4a Mon Sep 17 00:00:00 2001 From: beetrees Date: Thu, 31 Oct 2024 19:17:07 +0000 Subject: [PATCH 16/17] Remove `""` case from RISC-V `llvm_abiname` match statement --- compiler/rustc_codegen_ssa/src/back/metadata.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs index 4c25c85569b5d..796acb6796f26 100644 --- a/compiler/rustc_codegen_ssa/src/back/metadata.rs +++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs @@ -322,7 +322,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option (), + "ilp32" | "lp64" => (), "ilp32f" | "lp64f" => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE, "ilp32d" | "lp64d" => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE, // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI. From 9caced7badc337ced7ad89eb614621c39bd996e9 Mon Sep 17 00:00:00 2001 From: Matthew Maurer Date: Thu, 31 Oct 2024 20:35:24 +0000 Subject: [PATCH 17/17] llvm: Match new LLVM 128-bit integer alignment on sparc LLVM continues to align more 128-bit integers to 128-bits in the data layout rather than relying on the high level language to do it. Update SPARC target files to match and add a backcompat replacement for current LLVMs. See llvm/llvm-project#106951 for details --- compiler/rustc_codegen_llvm/src/context.rs | 5 +++++ .../src/spec/targets/sparc64_unknown_linux_gnu.rs | 2 +- .../rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs | 2 +- .../rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs | 2 +- .../rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs | 2 +- .../rustc_target/src/spec/targets/sparc_unknown_none_elf.rs | 2 +- .../rustc_target/src/spec/targets/sparcv9_sun_solaris.rs | 2 +- 7 files changed, 11 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 313957dda9642..13428b109d921 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -148,6 +148,11 @@ pub(crate) unsafe fn create_module<'ll>( target_data_layout = target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", ""); } + if sess.target.arch.starts_with("sparc") { + // LLVM 20 updates the sparc layout to correctly align 128 bit integers to 128 bit. + // See https://github.com/llvm/llvm-project/pull/106951 + target_data_layout = target_data_layout.replace("-i128:128", ""); + } } // Ensure the data-layout values hardcoded remain the defaults. diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs index 7d089aeb78714..ac2141f9b086c 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), arch: "sparc64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs index 21f09d6428ed4..d16b3776cfb14 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs @@ -16,7 +16,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), arch: "sparc64".into(), options: TargetOptions { endian: Endian::Big, mcount: "__mcount".into(), ..base }, } diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs index 12626dce47708..91e64061020ff 100644 --- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs +++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), arch: "sparc64".into(), options: base, } diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs index 08f0bb302dd47..2777395757f51 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs @@ -11,7 +11,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 32, - data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(), + data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(), arch: "sparc".into(), options: TargetOptions { cpu: "v9".into(), diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs index 0157d03f854b7..987f69429c069 100644 --- a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs +++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs @@ -17,7 +17,7 @@ pub(crate) fn target() -> Target { ..Default::default() }; Target { - data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(), + data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(), llvm_target: "sparc-unknown-none-elf".into(), metadata: crate::spec::TargetMetadata { description: Some("Bare 32-bit SPARC V7+".into()), diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs index 138ce902d5eba..fdc9628f78e8b 100644 --- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs +++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs @@ -19,7 +19,7 @@ pub(crate) fn target() -> Target { std: Some(true), }, pointer_width: 64, - data_layout: "E-m:e-i64:64-n32:64-S128".into(), + data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(), // Use "sparc64" instead of "sparcv9" here, since the former is already // used widely in the source base. If we ever needed ABI // differentiation from the sparc64, we could, but that would probably