From a04ac26a9d059809bee2daf778a9d92770963a81 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 28 May 2024 11:38:30 +0000 Subject: [PATCH 01/12] Allow type_of to return partially non-error types if the type was already tainted --- .../rustc_hir_analysis/src/collect/type_of.rs | 4 +- .../associated-inherent-types/issue-109071.rs | 2 +- .../issue-109071.with_gate.stderr | 17 +----- .../issues/issue-71381.full.stderr | 2 +- .../issues/issue-71381.min.stderr | 20 ++++++- tests/ui/const-generics/issues/issue-71381.rs | 2 + .../issues/issue-71611.min.stderr | 10 +++- tests/ui/const-generics/issues/issue-71611.rs | 1 + .../ice-type-mismatch-when-copying-112824.rs | 1 + ...e-type-mismatch-when-copying-112824.stderr | 8 ++- .../generic-associated-types/issue-71176.rs | 3 + .../issue-71176.stderr | 55 ++++++++++++++++++- tests/ui/layout/issue-84108.rs | 3 + tests/ui/layout/issue-84108.stderr | 36 ++++++++++-- .../ui/lifetimes/unusual-rib-combinations.rs | 6 +- .../lifetimes/unusual-rib-combinations.stderr | 37 +++++++------ .../issues/issue-103748-ICE-wrong-braces.rs | 1 + .../issue-103748-ICE-wrong-braces.stderr | 17 +++++- 18 files changed, 174 insertions(+), 51 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs index ed942cc50bb42..bc57b234555dc 100644 --- a/compiler/rustc_hir_analysis/src/collect/type_of.rs +++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs @@ -502,7 +502,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_ bug!("unexpected sort of node in type_of(): {:?}", x); } }; - if let Err(e) = icx.check_tainted_by_errors() { + if let Err(e) = icx.check_tainted_by_errors() + && !output.references_error() + { ty::EarlyBinder::bind(Ty::new_error(tcx, e)) } else { ty::EarlyBinder::bind(output) diff --git a/tests/ui/associated-inherent-types/issue-109071.rs b/tests/ui/associated-inherent-types/issue-109071.rs index 29eef081a3278..97803ae7191e1 100644 --- a/tests/ui/associated-inherent-types/issue-109071.rs +++ b/tests/ui/associated-inherent-types/issue-109071.rs @@ -13,7 +13,7 @@ impl Windows { //~ ERROR: missing generics for struct `Windows` impl Windows { fn T() -> Option {} - //~^ ERROR: ambiguous associated type + //[no_gate]~^ ERROR: ambiguous associated type } fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr b/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr index a7d17e2d5ebb9..1324cb9bb9b54 100644 --- a/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr +++ b/tests/ui/associated-inherent-types/issue-109071.with_gate.stderr @@ -20,20 +20,7 @@ help: add missing generic argument LL | impl Windows { | +++ -error[E0223]: ambiguous associated type - --> $DIR/issue-109071.rs:15:22 - | -LL | fn T() -> Option {} - | ^^^^^^^^^^ - | -help: use fully-qualified syntax - | -LL | fn T() -> Option< as IntoAsyncIterator>::Item> {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -LL | fn T() -> Option< as IntoIterator>::Item> {} - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0223, E0637. +Some errors have detailed explanations: E0107, E0637. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/const-generics/issues/issue-71381.full.stderr b/tests/ui/const-generics/issues/issue-71381.full.stderr index 5d7800746961b..b6460e0017fa5 100644 --- a/tests/ui/const-generics/issues/issue-71381.full.stderr +++ b/tests/ui/const-generics/issues/issue-71381.full.stderr @@ -7,7 +7,7 @@ LL | pub fn call_me $DIR/issue-71381.rs:22:40 + --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr index 5d7800746961b..e16d3b7a8a469 100644 --- a/tests/ui/const-generics/issues/issue-71381.min.stderr +++ b/tests/ui/const-generics/issues/issue-71381.min.stderr @@ -7,13 +7,29 @@ LL | pub fn call_me $DIR/issue-71381.rs:22:40 + --> $DIR/issue-71381.rs:23:40 | LL | const FN: unsafe extern "C" fn(Args), | ^^^^ the type must not depend on the parameter `Args` | = note: type parameters may not be used in the type of const parameters -error: aborting due to 2 previous errors +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71381.rs:14:61 + | +LL | pub fn call_me(&self) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71381.rs:23:19 + | +LL | const FN: unsafe extern "C" fn(Args), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71381.rs b/tests/ui/const-generics/issues/issue-71381.rs index 7f2e14944e296..e472ef31fcdd3 100644 --- a/tests/ui/const-generics/issues/issue-71381.rs +++ b/tests/ui/const-generics/issues/issue-71381.rs @@ -13,6 +13,7 @@ unsafe extern "C" fn pass(args: PassArg) { impl Test { pub fn call_me(&self) { //~^ ERROR: the type of const parameters must not depend on other generic parameters + //[min]~^^ ERROR: using function pointers as const generic parameters is forbidden self.0 = Self::trampiline:: as _ } @@ -21,6 +22,7 @@ impl Test { const IDX: usize, const FN: unsafe extern "C" fn(Args), //~^ ERROR: the type of const parameters must not depend on other generic parameters + //[min]~^^ ERROR: using function pointers as const generic parameters is forbidden >( args: Args, ) { diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr index 6f6a9fc21a699..b01936f4d2513 100644 --- a/tests/ui/const-generics/issues/issue-71611.min.stderr +++ b/tests/ui/const-generics/issues/issue-71611.min.stderr @@ -6,6 +6,14 @@ LL | fn func(outer: A) { | = note: type parameters may not be used in the type of const parameters -error: aborting due to 1 previous error +error: using function pointers as const generic parameters is forbidden + --> $DIR/issue-71611.rs:5:21 + | +LL | fn func(outer: A) { + | ^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0770`. diff --git a/tests/ui/const-generics/issues/issue-71611.rs b/tests/ui/const-generics/issues/issue-71611.rs index 0e0c08146b2ed..c6c1e267171f6 100644 --- a/tests/ui/const-generics/issues/issue-71611.rs +++ b/tests/ui/const-generics/issues/issue-71611.rs @@ -4,6 +4,7 @@ fn func(outer: A) { //~^ ERROR: the type of const parameters must not depend on other generic parameters + //[min]~| ERROR: using function pointers as const generic parameters is forbidden F(outer); } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs index a41a159c1fd7c..09f7e2ba5b1dd 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.rs @@ -13,6 +13,7 @@ impl Opcode2 { pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) { move |i| match msg_type { Opcode2::OP2 => unimplemented!(), + //~^ ERROR: could not evaluate constant pattern } } diff --git a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr index d95a8861230e0..9442eac0cf54a 100644 --- a/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr +++ b/tests/ui/const_prop/ice-type-mismatch-when-copying-112824.stderr @@ -17,7 +17,13 @@ help: you might be missing a type parameter LL | pub struct Opcode2(&'a S); | +++ -error: aborting due to 2 previous errors +error: could not evaluate constant pattern + --> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9 + | +LL | Opcode2::OP2 => unimplemented!(), + | ^^^^^^^^^^^^ + +error: aborting due to 3 previous errors Some errors have detailed explanations: E0261, E0412. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs index f0e162d825f9d..e58b6f6091e75 100644 --- a/tests/ui/generic-associated-types/issue-71176.rs +++ b/tests/ui/generic-associated-types/issue-71176.rs @@ -9,6 +9,9 @@ impl Provider for () { struct Holder { inner: Box>, //~^ ERROR: missing generics for associated type + //~| ERROR: missing generics for associated type + //~| ERROR: missing generics for associated type + //~| ERROR: the trait `Provider` cannot be made into an object } fn main() { diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index ed837f3475338..a1913bb618bc0 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -14,6 +14,57 @@ help: add missing lifetime argument LL | inner: Box = B>>, | ++++ -error: aborting due to 1 previous error +error[E0107]: missing generics for associated type `Provider::A` + --> $DIR/issue-71176.rs:10:27 + | +LL | inner: Box>, + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-71176.rs:2:10 + | +LL | type A<'a>; + | ^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | inner: Box = B>>, + | ++++ + +error[E0107]: missing generics for associated type `Provider::A` + --> $DIR/issue-71176.rs:10:27 + | +LL | inner: Box>, + | ^ expected 1 lifetime argument + | +note: associated type defined here, with 1 lifetime parameter: `'a` + --> $DIR/issue-71176.rs:2:10 + | +LL | type A<'a>; + | ^ -- + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: add missing lifetime argument + | +LL | inner: Box = B>>, + | ++++ + +error[E0038]: the trait `Provider` cannot be made into an object + --> $DIR/issue-71176.rs:10:14 + | +LL | inner: Box>, + | ^^^^^^^^^^^^^^^^^^^ `Provider` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-71176.rs:2:10 + | +LL | trait Provider { + | -------- this trait cannot be made into an object... +LL | type A<'a>; + | ^ ...because it contains the generic associated type `A` + = help: consider moving `A` to another trait + = help: only type `()` implements the trait, consider using it directly instead + +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0107`. +Some errors have detailed explanations: E0038, E0107. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 425da65b9905a..974d5310f6bb8 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -8,6 +8,9 @@ static FOO: (dyn AsRef, u8) = ("hello", 42); const BAR: (&Path, [u8], usize) = ("hello", [], 42); //~^ ERROR cannot find type `Path` in this scope +//~| ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR the size for values of type `[u8]` cannot be known at compilation time +//~| ERROR mismatched types static BAZ: ([u8], usize) = ([], 0); //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 6c168cc5fa84c..8ddce285e23f8 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -21,7 +21,35 @@ LL + use std::path::Path; | error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:12:13 + --> $DIR/issue-84108.rs:9:12 + | +LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-84108.rs:9:12 + | +LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); + | ^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `[u8]` + = note: only the last element of a tuple may have a dynamically sized type + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0308]: mismatched types + --> $DIR/issue-84108.rs:9:45 + | +LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42); + | ^^ expected `[u8]`, found `[_; 0]` + | + = note: expected slice `[u8]` + found array `[_; 0]` + +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time + --> $DIR/issue-84108.rs:15:13 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -30,7 +58,7 @@ LL | static BAZ: ([u8], usize) = ([], 0); = note: only the last element of a tuple may have a dynamically sized type error[E0277]: the size for values of type `[u8]` cannot be known at compilation time - --> $DIR/issue-84108.rs:12:13 + --> $DIR/issue-84108.rs:15:13 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^^^^^^^^^^^^ doesn't have a size known at compile-time @@ -40,7 +68,7 @@ LL | static BAZ: ([u8], usize) = ([], 0); = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` error[E0308]: mismatched types - --> $DIR/issue-84108.rs:12:30 + --> $DIR/issue-84108.rs:15:30 | LL | static BAZ: ([u8], usize) = ([], 0); | ^^ expected `[u8]`, found `[_; 0]` @@ -48,7 +76,7 @@ LL | static BAZ: ([u8], usize) = ([], 0); = note: expected slice `[u8]` found array `[_; 0]` -error: aborting due to 5 previous errors +error: aborting due to 8 previous errors Some errors have detailed explanations: E0277, E0308, E0412. For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/lifetimes/unusual-rib-combinations.rs b/tests/ui/lifetimes/unusual-rib-combinations.rs index 3bc87b9d480b4..0708a00d37157 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.rs +++ b/tests/ui/lifetimes/unusual-rib-combinations.rs @@ -2,9 +2,8 @@ struct S<'a>(&'a u8); fn foo() {} // Paren generic args in AnonConst -fn a() -> [u8; foo::()] { -//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait -//~| ERROR mismatched types +fn a() -> [u8; foo()] { + //~^ ERROR mismatched types panic!() } @@ -26,5 +25,6 @@ fn d() {} trait Foo<'a> {} struct Bar Foo<'a>)>; //~^ ERROR the type of const parameters must not depend on other generic parameters +//~| ERROR `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr index 2857fc72ea140..70f06b4be603c 100644 --- a/tests/ui/lifetimes/unusual-rib-combinations.stderr +++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr @@ -1,11 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/unusual-rib-combinations.rs:22:15 + --> $DIR/unusual-rib-combinations.rs:21:15 | LL | fn d() {} | ^ expected named lifetime parameter error[E0770]: the type of const parameters must not depend on other generic parameters - --> $DIR/unusual-rib-combinations.rs:27:22 + --> $DIR/unusual-rib-combinations.rs:26:22 | LL | struct Bar Foo<'a>)>; | ^^ the type must not depend on the parameter `'a` @@ -13,25 +13,19 @@ LL | struct Bar Foo<'a>)>; = note: lifetime parameters may not be used in the type of const parameters error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:5:16 - | -LL | fn a() -> [u8; foo::()] { - | ^^^^^^^ only `Fn` traits may use parentheses - -error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:12:15 + --> $DIR/unusual-rib-combinations.rs:11:15 | LL | fn b() {} | ^^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/unusual-rib-combinations.rs:16:10 + --> $DIR/unusual-rib-combinations.rs:15:10 | LL | fn c() {} | ^^^^ only `Fn` traits may use parentheses error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions - --> $DIR/unusual-rib-combinations.rs:16:6 + --> $DIR/unusual-rib-combinations.rs:15:6 | LL | fn c() {} | ^^^^^^^^ @@ -43,14 +37,11 @@ LL | fn c() {} error[E0308]: mismatched types --> $DIR/unusual-rib-combinations.rs:5:16 | -LL | fn a() -> [u8; foo::()] { - | ^^^^^^^ expected `usize`, found fn item - | - = note: expected type `usize` - found fn item `fn() {foo}` +LL | fn a() -> [u8; foo()] { + | ^^^^^ expected `usize`, found `()` error: `S<'_>` is forbidden as the type of a const generic parameter - --> $DIR/unusual-rib-combinations.rs:22:15 + --> $DIR/unusual-rib-combinations.rs:21:15 | LL | fn d() {} | ^ @@ -61,6 +52,18 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more LL + #![feature(adt_const_params)] | +error: `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter + --> $DIR/unusual-rib-combinations.rs:26:21 + | +LL | struct Bar Foo<'a>)>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: the only supported types are integers, `bool` and `char` +help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types + | +LL + #![feature(adt_const_params)] + | + error: aborting due to 8 previous errors Some errors have detailed explanations: E0106, E0214, E0308, E0770. diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs index f6aa39df27d8b..1c28c0632fa84 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.rs @@ -5,3 +5,4 @@ struct Apple((Apple, Option(Banana ? Citron))); //~| ERROR expected one of `)` or `,`, found `Citron` //~| ERROR cannot find type `Citron` in this scope [E0412] //~| ERROR parenthesized type parameters may only be used with a `Fn` trait [E0214] +//~| ERROR `Apple` has infinite size diff --git a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr index 71d2d7b797582..b0d8b03ae08c3 100644 --- a/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr +++ b/tests/ui/parser/issues/issue-103748-ICE-wrong-braces.stderr @@ -34,7 +34,18 @@ help: use angle brackets instead LL | struct Apple((Apple, Option)); | ~ ~ -error: aborting due to 4 previous errors +error[E0072]: recursive type `Apple` has infinite size + --> $DIR/issue-103748-ICE-wrong-braces.rs:3:1 + | +LL | struct Apple((Apple, Option(Banana ? Citron))); + | ^^^^^^^^^^^^ ----- recursive without indirection + | +help: insert some indirection (e.g., a `Box`, `Rc`, or `&`) to break the cycle + | +LL | struct Apple((Box, Option(Banana ? Citron))); + | ++++ + + +error: aborting due to 5 previous errors -Some errors have detailed explanations: E0214, E0412. -For more information about an error, try `rustc --explain E0214`. +Some errors have detailed explanations: E0072, E0214, E0412. +For more information about an error, try `rustc --explain E0072`. From 39b39da40beed5e4e555a1465dd0413b04afe91e Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 28 May 2024 16:05:13 +0000 Subject: [PATCH 02/12] Stop proving outlives constraints on regions we already reported errors on --- compiler/rustc_borrowck/src/nll.rs | 14 ++++- .../rustc_borrowck/src/universal_regions.rs | 20 ++++++- tests/rustdoc-ui/unable-fulfill-trait.rs | 13 ++-- tests/rustdoc-ui/unable-fulfill-trait.stderr | 31 +++++++--- .../associated-inherent-types/issue-109299.rs | 1 - .../issue-109299.stderr | 11 +--- .../ui/borrowck/generic_const_early_param.rs | 1 - .../borrowck/generic_const_early_param.stderr | 10 +--- .../gat-trait-path-missing-lifetime.rs | 1 - .../gat-trait-path-missing-lifetime.stderr | 11 +--- .../generic-associated-types/issue-70304.rs | 1 - .../issue-70304.stderr | 18 +----- .../generic-associated-types/issue-80433.rs | 3 +- .../issue-80433.stderr | 28 +-------- .../bad-item-bound-within-rpitit-2.rs | 2 - .../bad-item-bound-within-rpitit-2.stderr | 17 ++---- tests/ui/impl-trait/issues/issue-67830.rs | 7 +-- tests/ui/impl-trait/issues/issue-67830.stderr | 31 ++-------- tests/ui/impl-trait/issues/issue-88236-2.rs | 5 -- .../ui/impl-trait/issues/issue-88236-2.stderr | 60 +------------------ tests/ui/impl-trait/nested-rpit-hrtb.rs | 2 - tests/ui/impl-trait/nested-rpit-hrtb.stderr | 34 +++-------- tests/ui/lifetimes/issue-69314.fixed | 2 +- tests/ui/lifetimes/issue-69314.rs | 2 +- tests/ui/lifetimes/issue-69314.stderr | 18 +----- 25 files changed, 97 insertions(+), 246 deletions(-) diff --git a/compiler/rustc_borrowck/src/nll.rs b/compiler/rustc_borrowck/src/nll.rs index 49f50babdcb96..5d7ce548469fb 100644 --- a/compiler/rustc_borrowck/src/nll.rs +++ b/compiler/rustc_borrowck/src/nll.rs @@ -125,8 +125,8 @@ pub(crate) fn compute_regions<'cx, 'tcx>( placeholder_indices, placeholder_index_to_region: _, liveness_constraints, - outlives_constraints, - member_constraints, + mut outlives_constraints, + mut member_constraints, universe_causes, type_tests, } = constraints; @@ -144,6 +144,16 @@ pub(crate) fn compute_regions<'cx, 'tcx>( &universal_region_relations, ); + if let Some(guar) = universal_regions.tainted_by_errors() { + // Suppress unhelpful extra errors in `infer_opaque_types` by clearing out all + // outlives bounds that we may end up checking. + outlives_constraints = Default::default(); + member_constraints = Default::default(); + + // Also taint the entire scope. + infcx.set_tainted_by_errors(guar); + } + let mut regioncx = RegionInferenceContext::new( infcx, var_origins, diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs index f8123535e2d0a..9f5fb59e46c55 100644 --- a/compiler/rustc_borrowck/src/universal_regions.rs +++ b/compiler/rustc_borrowck/src/universal_regions.rs @@ -29,7 +29,8 @@ use rustc_middle::ty::{self, InlineConstArgs, InlineConstArgsParts, RegionVid, T use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_middle::{bug, span_bug}; use rustc_span::symbol::{kw, sym}; -use rustc_span::Symbol; +use rustc_span::{ErrorGuaranteed, Symbol}; +use std::cell::Cell; use std::iter; use crate::renumber::RegionCtxt; @@ -186,6 +187,10 @@ struct UniversalRegionIndices<'tcx> { /// The vid assigned to `'static`. Used only for diagnostics. pub fr_static: RegionVid, + + /// Whether we've encountered an error region. If we have, cancel all + /// outlives errors, as they are likely bogus. + pub tainted_by_errors: Cell>, } #[derive(Debug, PartialEq)] @@ -408,6 +413,10 @@ impl<'tcx> UniversalRegions<'tcx> { } } } + + pub fn tainted_by_errors(&self) -> Option { + self.indices.tainted_by_errors.get() + } } struct UniversalRegionsBuilder<'cx, 'tcx> { @@ -663,7 +672,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> { let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static)); let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var())); - UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static } + UniversalRegionIndices { + indices: global_mapping.chain(arg_mapping).collect(), + fr_static, + tainted_by_errors: Cell::new(None), + } } fn compute_inputs_and_output( @@ -868,7 +881,8 @@ impl<'tcx> UniversalRegionIndices<'tcx> { pub fn to_region_vid(&self, r: ty::Region<'tcx>) -> RegionVid { if let ty::ReVar(..) = *r { r.as_var() - } else if r.is_error() { + } else if let ty::ReError(guar) = *r { + self.tainted_by_errors.set(Some(guar)); // We use the `'static` `RegionVid` because `ReError` doesn't actually exist in the // `UniversalRegionIndices`. This is fine because 1) it is a fallback only used if // errors are being emitted and 2) it leaves the happy path unaffected. diff --git a/tests/rustdoc-ui/unable-fulfill-trait.rs b/tests/rustdoc-ui/unable-fulfill-trait.rs index a69f74b09ac04..f3b6256346f0c 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.rs +++ b/tests/rustdoc-ui/unable-fulfill-trait.rs @@ -1,13 +1,16 @@ // This test ensures that it's not crashing rustdoc. pub struct Foo<'a, 'b, T> { - field1: dyn Bar<'a, 'b,>, + field1: dyn Bar<'a, 'b>, //~^ ERROR //~| ERROR + //~| ERROR } pub trait Bar<'x, 's, U> - where U: 'x, - Self:'x, - Self:'s -{} +where + U: 'x, + Self: 'x, + Self: 's, +{ +} diff --git a/tests/rustdoc-ui/unable-fulfill-trait.stderr b/tests/rustdoc-ui/unable-fulfill-trait.stderr index 72f35cb922445..40d103f2a62e7 100644 --- a/tests/rustdoc-ui/unable-fulfill-trait.stderr +++ b/tests/rustdoc-ui/unable-fulfill-trait.stderr @@ -1,26 +1,43 @@ error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied --> $DIR/unable-fulfill-trait.rs:4:17 | -LL | field1: dyn Bar<'a, 'b,>, +LL | field1: dyn Bar<'a, 'b>, | ^^^ expected 1 generic argument | note: trait defined here, with 1 generic parameter: `U` - --> $DIR/unable-fulfill-trait.rs:9:11 + --> $DIR/unable-fulfill-trait.rs:10:11 | LL | pub trait Bar<'x, 's, U> | ^^^ - help: add missing generic argument | -LL | field1: dyn Bar<'a, 'b, U,>, +LL | field1: dyn Bar<'a, 'b, U>, | +++ error[E0227]: ambiguous lifetime bound, explicit lifetime bound required --> $DIR/unable-fulfill-trait.rs:4:13 | -LL | field1: dyn Bar<'a, 'b,>, - | ^^^^^^^^^^^^^^^^ +LL | field1: dyn Bar<'a, 'b>, + | ^^^^^^^^^^^^^^^ -error: aborting due to 2 previous errors +error[E0478]: lifetime bound not satisfied + --> $DIR/unable-fulfill-trait.rs:4:13 + | +LL | field1: dyn Bar<'a, 'b>, + | ^^^^^^^^^^^^^^^ + | +note: lifetime parameter instantiated with the lifetime `'b` as defined here + --> $DIR/unable-fulfill-trait.rs:3:20 + | +LL | pub struct Foo<'a, 'b, T> { + | ^^ +note: but lifetime parameter must outlive the lifetime `'a` as defined here + --> $DIR/unable-fulfill-trait.rs:3:16 + | +LL | pub struct Foo<'a, 'b, T> { + | ^^ + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0227. +Some errors have detailed explanations: E0107, E0227, E0478. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/associated-inherent-types/issue-109299.rs b/tests/ui/associated-inherent-types/issue-109299.rs index b6c010c34e441..84e4f9e72527a 100644 --- a/tests/ui/associated-inherent-types/issue-109299.rs +++ b/tests/ui/associated-inherent-types/issue-109299.rs @@ -8,6 +8,5 @@ impl Lexer<'d> { //~ ERROR use of undeclared lifetime name `'d` } fn test(_: Lexer::Cursor) {} -//~^ ERROR: lifetime may not live long enough fn main() {} diff --git a/tests/ui/associated-inherent-types/issue-109299.stderr b/tests/ui/associated-inherent-types/issue-109299.stderr index f108a52b92c08..1e11c0e8c2af1 100644 --- a/tests/ui/associated-inherent-types/issue-109299.stderr +++ b/tests/ui/associated-inherent-types/issue-109299.stderr @@ -6,15 +6,6 @@ LL | impl Lexer<'d> { | | | help: consider introducing lifetime `'d` here: `<'d>` -error: lifetime may not live long enough - --> $DIR/issue-109299.rs:10:1 - | -LL | fn test(_: Lexer::Cursor) {} - | ^^^^^^^^-^^^^^^^^^^^^^^^^ - | | | - | | has type `Lexer<'1>::Cursor` - | requires that `'1` must outlive `'static` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/borrowck/generic_const_early_param.rs b/tests/ui/borrowck/generic_const_early_param.rs index f601e45d21fee..0d07b6869f122 100644 --- a/tests/ui/borrowck/generic_const_early_param.rs +++ b/tests/ui/borrowck/generic_const_early_param.rs @@ -5,7 +5,6 @@ struct DataWrapper<'static> { //~^ ERROR invalid lifetime parameter name: `'static` data: &'a [u8; Self::SIZE], //~^ ERROR use of undeclared lifetime name `'a` - //~^^ ERROR lifetime may not live long enough } impl DataWrapper<'a> { diff --git a/tests/ui/borrowck/generic_const_early_param.stderr b/tests/ui/borrowck/generic_const_early_param.stderr index a71ab09396e73..3f56d6a332515 100644 --- a/tests/ui/borrowck/generic_const_early_param.stderr +++ b/tests/ui/borrowck/generic_const_early_param.stderr @@ -14,7 +14,7 @@ LL | data: &'a [u8; Self::SIZE], | ^^ undeclared lifetime error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/generic_const_early_param.rs:11:18 + --> $DIR/generic_const_early_param.rs:10:18 | LL | impl DataWrapper<'a> { | - ^^ undeclared lifetime @@ -30,13 +30,7 @@ LL | #![feature(generic_const_exprs)] = note: see issue #76560 for more information = note: `#[warn(incomplete_features)]` on by default -error: lifetime may not live long enough - --> $DIR/generic_const_early_param.rs:6:20 - | -LL | data: &'a [u8; Self::SIZE], - | ^^^^^^^^^^ requires that `'_` must outlive `'static` - -error: aborting due to 4 previous errors; 1 warning emitted +error: aborting due to 3 previous errors; 1 warning emitted Some errors have detailed explanations: E0261, E0262. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs index 671d17f36f13d..285493132b64d 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.rs @@ -9,7 +9,6 @@ impl X for T { //~ ERROR: not all trait items implemented //~^ ERROR missing generics for associated type //~^^ ERROR missing generics for associated type //~| ERROR method `foo` has 1 type parameter but its trait declaration has 0 type parameters - //~| ERROR may not live long enough t } } diff --git a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr index 65854ed71587b..6a600aee11f2f 100644 --- a/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr +++ b/tests/ui/generic-associated-types/gat-trait-path-missing-lifetime.stderr @@ -51,16 +51,7 @@ help: add missing lifetime argument LL | fn foo<'a, T1: X = T1>>(t : T1) -> T1::Y<'a> { | ++++ -error: lifetime may not live long enough - --> $DIR/gat-trait-path-missing-lifetime.rs:8:3 - | -LL | fn foo<'a, T1: X>(t : T1) -> T1::Y<'a> { - | ^^^^^^^--^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | | | - | | lifetime `'a` defined here - | requires that `'a` must outlive `'static` - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0046, E0049, E0107. For more information about an error, try `rustc --explain E0046`. diff --git a/tests/ui/generic-associated-types/issue-70304.rs b/tests/ui/generic-associated-types/issue-70304.rs index 935d3f7a4ba8f..8898d4c7d1352 100644 --- a/tests/ui/generic-associated-types/issue-70304.rs +++ b/tests/ui/generic-associated-types/issue-70304.rs @@ -52,5 +52,4 @@ fn create_doc() -> impl Document = DocCursorImpl<'_>> { pub fn main() { let doc = create_doc(); let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc); - //~^ ERROR: `doc` does not live long enough } diff --git a/tests/ui/generic-associated-types/issue-70304.stderr b/tests/ui/generic-associated-types/issue-70304.stderr index 8e012cc6d9367..9b02c1b076837 100644 --- a/tests/ui/generic-associated-types/issue-70304.stderr +++ b/tests/ui/generic-associated-types/issue-70304.stderr @@ -27,21 +27,7 @@ LL | type Cursor<'a>: DocCursor<'a>; = note: this bound is currently required to ensure that impls have maximum flexibility = note: we are soliciting feedback, see issue #87479 for more information -error[E0597]: `doc` does not live long enough - --> $DIR/issue-70304.rs:54:59 - | -LL | let doc = create_doc(); - | --- binding `doc` declared here -LL | let lexer: Lexer<'_, DocCursorImpl<'_>> = Lexer::from(&doc); - | ------------^^^^- - | | | - | | borrowed value does not live long enough - | argument requires that `doc` is borrowed for `'static` -LL | -LL | } - | - `doc` dropped here while still borrowed - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0106, E0597, E0637. +Some errors have detailed explanations: E0106, E0637. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/generic-associated-types/issue-80433.rs b/tests/ui/generic-associated-types/issue-80433.rs index 5305754244025..bdba78c2ccd26 100644 --- a/tests/ui/generic-associated-types/issue-80433.rs +++ b/tests/ui/generic-associated-types/issue-80433.rs @@ -22,8 +22,7 @@ fn test_simpler<'a>(dst: &'a mut impl TestMut) //~^ ERROR missing generics for associated type { for n in 0i16..100 { - *dst.test_mut() = n.into(); //~ ERROR: cannot borrow - //~^ ERROR: borrowed data escapes outside of function + *dst.test_mut() = n.into(); } } diff --git a/tests/ui/generic-associated-types/issue-80433.stderr b/tests/ui/generic-associated-types/issue-80433.stderr index a9a14d3f51ced..8ab6fdcb81573 100644 --- a/tests/ui/generic-associated-types/issue-80433.stderr +++ b/tests/ui/generic-associated-types/issue-80433.stderr @@ -25,30 +25,6 @@ help: add missing lifetime argument LL | fn test_simpler<'a>(dst: &'a mut impl TestMut = &'a mut f32>) | ++++ -error[E0499]: cannot borrow `*dst` as mutable more than once at a time - --> $DIR/issue-80433.rs:25:10 - | -LL | *dst.test_mut() = n.into(); - | ^^^----------- - | | - | `*dst` was mutably borrowed here in the previous iteration of the loop - | argument requires that `*dst` is borrowed for `'static` - -error[E0521]: borrowed data escapes outside of function - --> $DIR/issue-80433.rs:25:10 - | -LL | fn test_simpler<'a>(dst: &'a mut impl TestMut) - | -- --- `dst` is a reference that is only valid in the function body - | | - | lifetime `'a` defined here -... -LL | *dst.test_mut() = n.into(); - | ^^^^^^^^^^^^^^ - | | - | `dst` escapes the function body here - | argument requires that `'a` must outlive `'static` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0107, E0499, E0521. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs index 5b3a4eb53ff15..14b1ebea8db23 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.rs @@ -1,11 +1,9 @@ // issue: 114146 - trait Foo { fn bar<'other: 'a>() -> impl Sized + 'a {} //~^ ERROR use of undeclared lifetime name `'a` //~| ERROR use of undeclared lifetime name `'a` - //~| ERROR expected generic lifetime parameter, found `'static` } fn main() {} diff --git a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr index 8975578dabd84..f1b006da1db50 100644 --- a/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr +++ b/tests/ui/impl-trait/in-trait/bad-item-bound-within-rpitit-2.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/bad-item-bound-within-rpitit-2.rs:5:20 + --> $DIR/bad-item-bound-within-rpitit-2.rs:4:20 | LL | fn bar<'other: 'a>() -> impl Sized + 'a {} | ^^ undeclared lifetime @@ -14,7 +14,7 @@ LL | trait Foo<'a> { | ++++ error[E0261]: use of undeclared lifetime name `'a` - --> $DIR/bad-item-bound-within-rpitit-2.rs:5:42 + --> $DIR/bad-item-bound-within-rpitit-2.rs:4:42 | LL | fn bar<'other: 'a>() -> impl Sized + 'a {} | ^^ undeclared lifetime @@ -28,15 +28,6 @@ help: consider introducing lifetime `'a` here LL | trait Foo<'a> { | ++++ -error[E0792]: expected generic lifetime parameter, found `'static` - --> $DIR/bad-item-bound-within-rpitit-2.rs:5:45 - | -LL | fn bar<'other: 'a>() -> impl Sized + 'a {} - | ------ ^^ - | | - | cannot use static lifetime; use a bound lifetime instead or remove the lifetime parameter from the opaque type - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0261, E0792. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/impl-trait/issues/issue-67830.rs b/tests/ui/impl-trait/issues/issue-67830.rs index 939eca82a8f6d..28772fa527200 100644 --- a/tests/ui/impl-trait/issues/issue-67830.rs +++ b/tests/ui/impl-trait/issues/issue-67830.rs @@ -7,7 +7,7 @@ struct Wrap(F); impl MyFn for Wrap where - F: Fn(A) -> B + F: Fn(A) -> B, { type Output = B; @@ -16,13 +16,10 @@ where } } - struct A; -fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { +fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` Wrap(|a| Some(a).into_iter()) - //~^ ERROR implementation of `FnOnce` is not general enough - //~| ERROR implementation of `FnOnce` is not general enough } fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-67830.stderr b/tests/ui/impl-trait/issues/issue-67830.stderr index ef513a40cf39f..a7633c7f20b65 100644 --- a/tests/ui/impl-trait/issues/issue-67830.stderr +++ b/tests/ui/impl-trait/issues/issue-67830.stderr @@ -1,34 +1,15 @@ error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-67830.rs:21:62 + --> $DIR/issue-67830.rs:20:64 | -LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { - | ^^ +LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { + | ^^ | note: lifetime declared here - --> $DIR/issue-67830.rs:21:23 + --> $DIR/issue-67830.rs:20:23 | -LL | fn test() -> impl for<'a> MyFn<&'a A, Output=impl Iterator + 'a> { +LL | fn test() -> impl for<'a> MyFn<&'a A, Output = impl Iterator + 'a> { | ^^ -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-67830.rs:23:5 - | -LL | Wrap(|a| Some(a).into_iter()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` - -error: implementation of `FnOnce` is not general enough - --> $DIR/issue-67830.rs:23:5 - | -LL | Wrap(|a| Some(a).into_iter()) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough - | - = note: closure with signature `fn(&'2 A) -> std::option::IntoIter<&A>` must implement `FnOnce<(&'1 A,)>`, for any lifetime `'1`... - = note: ...but it actually implements `FnOnce<(&'2 A,)>`, for some specific lifetime `'2` - = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/issues/issue-88236-2.rs b/tests/ui/impl-trait/issues/issue-88236-2.rs index 7ff08d8174f8e..5005af46ee187 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.rs +++ b/tests/ui/impl-trait/issues/issue-88236-2.rs @@ -18,16 +18,11 @@ fn make_impl() -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> {} fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` &() - //~^ ERROR implementation of `Hrtb` is not general enough - //~| ERROR implementation of `Hrtb` is not general enough } fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` x - //~^ ERROR implementation of `Hrtb` is not general enough - //~| ERROR implementation of `Hrtb` is not general enough - //~| ERROR lifetime may not live long enough } fn main() {} diff --git a/tests/ui/impl-trait/issues/issue-88236-2.stderr b/tests/ui/impl-trait/issues/issue-88236-2.stderr index 09fd58056a561..4ded9ed386fa6 100644 --- a/tests/ui/impl-trait/issues/issue-88236-2.stderr +++ b/tests/ui/impl-trait/issues/issue-88236-2.stderr @@ -22,72 +22,18 @@ note: lifetime declared here LL | fn make_weird_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:20:5 - | -LL | &() - | ^^^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'a>` would have to be implemented for the type `&()` - = note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0` - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/issue-88236-2.rs:25:78 + --> $DIR/issue-88236-2.rs:23:78 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ | note: lifetime declared here - --> $DIR/issue-88236-2.rs:25:45 + --> $DIR/issue-88236-2.rs:23:45 | LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { | ^^ -error: lifetime may not live long enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> { - | -- lifetime `'b` defined here -LL | -LL | x - | ^ returning this value requires that `'b` must outlive `'static` - | -help: to declare that `impl for<'a> Hrtb<'a, Assoc = impl Send + '_>` captures data from argument `x`, you can add an explicit `'b` lifetime bound - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a> + 'b { - | ++++ -help: to declare that `impl Send + 'a` captures data from argument `x`, you can add an explicit `'b` lifetime bound - | -LL | fn make_bad_impl<'b>(x: &'b ()) -> impl for<'a> Hrtb<'a, Assoc = impl Send + 'a + 'b> { - | ++++ - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'0>` would have to be implemented for the type `&()`, for any lifetime `'0`... - = note: ...but `Hrtb<'1>` is actually implemented for the type `&'1 ()`, for some specific lifetime `'1` - -error: implementation of `Hrtb` is not general enough - --> $DIR/issue-88236-2.rs:27:5 - | -LL | x - | ^ implementation of `Hrtb` is not general enough - | - = note: `Hrtb<'a>` would have to be implemented for the type `&()` - = note: ...but `Hrtb<'0>` is actually implemented for the type `&'0 ()`, for some specific lifetime `'0` - -error: aborting due to 8 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs index 9b18aceb4a731..11d79bcff7371 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.rs +++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs @@ -31,7 +31,6 @@ fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` -//~| ERROR implementation of `Bar` is not general enough fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` @@ -64,6 +63,5 @@ fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux< // `'b` is not in scope for the outlives bound. fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} //~^ ERROR use of undeclared lifetime name `'b` [E0261] -//~| ERROR implementation of `Bar` is not general enough fn main() {} diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index 2fa036f35fab3..d98de650d0d88 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:57:77 + --> $DIR/nested-rpit-hrtb.rs:56:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:65:82 + --> $DIR/nested-rpit-hrtb.rs:64:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -65,29 +65,20 @@ note: lifetime declared here LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} | ^^ -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:32:78 - | -LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'a>` - = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:36:73 + --> $DIR/nested-rpit-hrtb.rs:35:73 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ | note: lifetime declared here - --> $DIR/nested-rpit-hrtb.rs:36:44 + --> $DIR/nested-rpit-hrtb.rs:35:44 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:46:79 + --> $DIR/nested-rpit-hrtb.rs:45:79 | LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} | ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()` @@ -96,7 +87,7 @@ LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:50:93 + --> $DIR/nested-rpit-hrtb.rs:49:93 | LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -105,7 +96,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:61:64 + --> $DIR/nested-rpit-hrtb.rs:60:64 | LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()` @@ -113,16 +104,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> = help: the trait `Qux<'_>` is implemented for `()` = help: for that trait implementation, expected `()`, found `&'a ()` -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:65:86 - | -LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'a>` - = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` - -error: aborting due to 11 previous errors +error: aborting due to 9 previous errors Some errors have detailed explanations: E0261, E0277, E0657. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/lifetimes/issue-69314.fixed b/tests/ui/lifetimes/issue-69314.fixed index 285d192b44c76..ee1675724fb12 100644 --- a/tests/ui/lifetimes/issue-69314.fixed +++ b/tests/ui/lifetimes/issue-69314.fixed @@ -11,7 +11,7 @@ impl A { } async fn f() { let mut buf = [0; 512]; - let m2 = &buf[..]; //~ ERROR `buf` does not live long enough + let m2 = &buf[..]; let m = Self::g(m2).await; Self::f2(m).await; } diff --git a/tests/ui/lifetimes/issue-69314.rs b/tests/ui/lifetimes/issue-69314.rs index 345f77850608d..f9e5196b2c74e 100644 --- a/tests/ui/lifetimes/issue-69314.rs +++ b/tests/ui/lifetimes/issue-69314.rs @@ -11,7 +11,7 @@ impl A { } async fn f() { let mut buf = [0; 512]; - let m2 = &buf[..]; //~ ERROR `buf` does not live long enough + let m2 = &buf[..]; let m = Self::g(m2).await; Self::f2(m).await; } diff --git a/tests/ui/lifetimes/issue-69314.stderr b/tests/ui/lifetimes/issue-69314.stderr index 3879f35505c2e..67da54e8dcd7c 100644 --- a/tests/ui/lifetimes/issue-69314.stderr +++ b/tests/ui/lifetimes/issue-69314.stderr @@ -9,20 +9,6 @@ help: indicate the anonymous lifetime LL | async fn f2(m: Msg<'_>) {} | ++++ -error[E0597]: `buf` does not live long enough - --> $DIR/issue-69314.rs:14:19 - | -LL | let mut buf = [0; 512]; - | ------- binding `buf` declared here -LL | let m2 = &buf[..]; - | ^^^ borrowed value does not live long enough -LL | let m = Self::g(m2).await; - | ----------- argument requires that `buf` is borrowed for `'static` -LL | Self::f2(m).await; -LL | } - | - `buf` dropped here while still borrowed - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0597, E0726. -For more information about an error, try `rustc --explain E0597`. +For more information about this error, try `rustc --explain E0726`. From f9adc1ee9d5b94d4ccb744cf686091c16849a4ee Mon Sep 17 00:00:00 2001 From: Georg Semmler Date: Wed, 29 May 2024 08:59:06 +0200 Subject: [PATCH 03/12] Refactor `#[diagnostic::do_not_recommend]` support This commit refactors the `#[do_not_recommend]` support in the old parser to also apply to projection errors and not only to selection errors. This allows the attribute to be used more widely. --- .../error_reporting/type_err_ctxt_ext.rs | 26 ++++++++++++------ .../type_mismatch.current.stderr | 15 +++++++++++ .../type_mismatch.next.stderr | 15 +++++++++++ .../do_not_recommend/type_mismatch.rs | 27 +++++++++++++++++++ 4 files changed, 75 insertions(+), 8 deletions(-) create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr create mode 100644 tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs index 46953a61296ac..642bb3a6e1bed 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs @@ -414,7 +414,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_predicate)) => { let trait_predicate = bound_predicate.rebind(trait_predicate); let trait_predicate = self.resolve_vars_if_possible(trait_predicate); - let trait_predicate = self.apply_do_not_recommend(trait_predicate, &mut obligation); // Let's use the root obligation as the main message, when we care about the // most general case ("X doesn't implement Pattern<'_>") over the case that @@ -996,12 +995,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.emit() } - fn apply_do_not_recommend( - &self, - mut trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, - obligation: &'_ mut PredicateObligation<'tcx>, - ) -> ty::Binder<'tcx, ty::TraitPredicate<'tcx>> { + fn apply_do_not_recommend(&self, obligation: &mut PredicateObligation<'tcx>) -> bool { let mut base_cause = obligation.cause.code().clone(); + let mut applied_do_not_recommend = false; loop { if let ObligationCauseCode::ImplDerived(ref c) = base_cause { if self.tcx.has_attrs_with_path( @@ -1011,7 +1007,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { let code = (*c.derived.parent_code).clone(); obligation.cause.map_code(|_| code); obligation.predicate = c.derived.parent_trait_pred.upcast(self.tcx); - trait_predicate = c.derived.parent_trait_pred.clone(); + applied_do_not_recommend = true; } } if let Some((parent_cause, _parent_pred)) = base_cause.parent() { @@ -1021,7 +1017,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { } } - trait_predicate + applied_do_not_recommend } fn emit_specialized_closure_kind_error( @@ -1521,6 +1517,20 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { #[instrument(skip(self), level = "debug")] fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) -> ErrorGuaranteed { + let mut error = FulfillmentError { + obligation: error.obligation.clone(), + code: error.code.clone(), + root_obligation: error.root_obligation.clone(), + }; + if matches!( + error.code, + FulfillmentErrorCode::Select(crate::traits::SelectionError::Unimplemented) + | FulfillmentErrorCode::Project(_) + ) && self.apply_do_not_recommend(&mut error.obligation) + { + error.code = FulfillmentErrorCode::Select(SelectionError::Unimplemented); + } + match error.code { FulfillmentErrorCode::Select(ref selection_error) => self.report_selection_error( error.obligation.clone(), diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr new file mode 100644 index 0000000000000..bcede8a255f23 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.current.stderr @@ -0,0 +1,15 @@ +error[E0277]: Very important message! + --> $DIR/type_mismatch.rs:25:14 + | +LL | verify::(); + | ^^ the trait `TheImportantOne` is not implemented for `u8` + | +note: required by a bound in `verify` + --> $DIR/type_mismatch.rs:22:14 + | +LL | fn verify() {} + | ^^^^^^^^^^^^^^^ required by this bound in `verify` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr new file mode 100644 index 0000000000000..bcede8a255f23 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.next.stderr @@ -0,0 +1,15 @@ +error[E0277]: Very important message! + --> $DIR/type_mismatch.rs:25:14 + | +LL | verify::(); + | ^^ the trait `TheImportantOne` is not implemented for `u8` + | +note: required by a bound in `verify` + --> $DIR/type_mismatch.rs:22:14 + | +LL | fn verify() {} + | ^^^^^^^^^^^^^^^ required by this bound in `verify` + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs new file mode 100644 index 0000000000000..d6721ccc848f8 --- /dev/null +++ b/tests/ui/diagnostic_namespace/do_not_recommend/type_mismatch.rs @@ -0,0 +1,27 @@ +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver + +#![feature(do_not_recommend)] + +#[diagnostic::on_unimplemented(message = "Very important message!")] +trait TheImportantOne {} + +trait ImplementationDetail { + type Restriction; +} + +#[diagnostic::do_not_recommend] +impl> TheImportantOne for T {} + +// Comment out this `impl` to show the expected error message. +impl ImplementationDetail for u8 { + type Restriction = u8; +} + +fn verify() {} + +pub fn main() { + verify::(); + //~^ERROR: Very important message! [E0277] +} From 08fe940f0a47f7281ec916a924ec978cac994491 Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroch Date: Thu, 30 May 2024 21:39:12 -0500 Subject: [PATCH 04/12] Improve renaming suggestion for names with leading underscores --- compiler/rustc_resolve/src/diagnostics.rs | 38 ++++++++++++++--------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 856cfbc01e8cd..d1541527cf595 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1562,6 +1562,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Some(suggestion) if suggestion.candidate == kw::Underscore => return false, Some(suggestion) => suggestion, }; + + let mut did_label_def_span = false; + if let Some(def_span) = suggestion.res.opt_def_id().map(|def_id| self.def_span(def_id)) { if span.overlaps(def_span) { // Don't suggest typo suggestion for itself like in the following: @@ -1595,31 +1598,38 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { errors::DefinedHere::SingleItem { span, candidate_descr, candidate } } }; + did_label_def_span = true; err.subdiagnostic(self.tcx.dcx(), label); } - let (span, sugg, post) = if let SuggestionTarget::SimilarlyNamed = suggestion.target + let (span, msg, sugg) = if let SuggestionTarget::SimilarlyNamed = suggestion.target && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) && let Some(span) = suggestion.span && let Some(candidate) = suggestion.candidate.as_str().strip_prefix('_') && snippet == candidate { + let candidate = suggestion.candidate; // When the suggested binding change would be from `x` to `_x`, suggest changing the // original binding definition instead. (#60164) - let post = format!(", consider renaming `{}` into `{snippet}`", suggestion.candidate); - (span, snippet, post) - } else { - (span, suggestion.candidate.to_ident_string(), String::new()) - }; - let msg = match suggestion.target { - SuggestionTarget::SimilarlyNamed => format!( - "{} {} with a similar name exists{post}", - suggestion.res.article(), - suggestion.res.descr() - ), - SuggestionTarget::SingleItem => { - format!("maybe you meant this {}", suggestion.res.descr()) + let msg = format!( + "the leading underscore in `{candidate}` marks it as unused, consider renaming it to `{snippet}`" + ); + if !did_label_def_span { + err.span_label(span, format!("`{candidate}` defined here")); } + (span, msg, snippet) + } else { + let msg = match suggestion.target { + SuggestionTarget::SimilarlyNamed => format!( + "{} {} with a similar name exists", + suggestion.res.article(), + suggestion.res.descr() + ), + SuggestionTarget::SingleItem => { + format!("maybe you meant this {}", suggestion.res.descr()) + } + }; + (span, msg, suggestion.candidate.to_ident_string()) }; err.span_suggestion(span, msg, sugg, Applicability::MaybeIncorrect); true From 9af96745d693b5b263fab27c84d7cb55465ca09b Mon Sep 17 00:00:00 2001 From: Lucas Scharenbroch Date: Thu, 30 May 2024 21:39:41 -0500 Subject: [PATCH 05/12] Update ui tests for leading-underscore suggestion --- tests/ui/macros/expand-full-no-resolution.stderr | 4 ++-- tests/ui/suggestions/silenced-binding-typo.stderr | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/ui/macros/expand-full-no-resolution.stderr b/tests/ui/macros/expand-full-no-resolution.stderr index 2537a5032a92d..df6f20332bfd8 100644 --- a/tests/ui/macros/expand-full-no-resolution.stderr +++ b/tests/ui/macros/expand-full-no-resolution.stderr @@ -7,7 +7,7 @@ LL | macro_rules! _a { LL | format_args!(a!()); | ^ | -help: a macro with a similar name exists, consider renaming `_a` into `a` +help: the leading underscore in `_a` marks it as unused, consider renaming it to `a` | LL | macro_rules! a { | ~ @@ -21,7 +21,7 @@ LL | macro_rules! _a { LL | env!(a!()); | ^ | -help: a macro with a similar name exists, consider renaming `_a` into `a` +help: the leading underscore in `_a` marks it as unused, consider renaming it to `a` | LL | macro_rules! a { | ~ diff --git a/tests/ui/suggestions/silenced-binding-typo.stderr b/tests/ui/suggestions/silenced-binding-typo.stderr index c362d00c713a2..a1e8b9e30d4b7 100644 --- a/tests/ui/suggestions/silenced-binding-typo.stderr +++ b/tests/ui/suggestions/silenced-binding-typo.stderr @@ -1,10 +1,12 @@ error[E0425]: cannot find value `x` in this scope --> $DIR/silenced-binding-typo.rs:4:14 | +LL | let _x = 42; + | -- `_x` defined here LL | let _y = x; | ^ | -help: a local variable with a similar name exists, consider renaming `_x` into `x` +help: the leading underscore in `_x` marks it as unused, consider renaming it to `x` | LL | let x = 42; | ~ From 66a13861aee8f3754dbec65af21c2ef6ca9756f9 Mon Sep 17 00:00:00 2001 From: Andrew Wock Date: Sat, 1 Jun 2024 14:59:13 -0400 Subject: [PATCH 06/12] Fix ICE caused by ignoring EffectVars in type inference Signed-off-by: Andrew Wock --- compiler/rustc_infer/src/infer/mod.rs | 2 + compiler/rustc_infer/src/infer/resolve.rs | 3 + tests/crashes/119830.rs | 11 --- .../effects/spec-effectvar-ice.rs | 24 +++++++ .../effects/spec-effectvar-ice.stderr | 69 +++++++++++++++++++ 5 files changed, 98 insertions(+), 11 deletions(-) delete mode 100644 tests/crashes/119830.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs create mode 100644 tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs index c8bb6cf5f9b4c..cb93ef7fdb07f 100644 --- a/compiler/rustc_infer/src/infer/mod.rs +++ b/compiler/rustc_infer/src/infer/mod.rs @@ -587,6 +587,7 @@ pub enum FixupError { UnresolvedFloatTy(FloatVid), UnresolvedTy(TyVid), UnresolvedConst(ConstVid), + UnresolvedEffect(EffectVid), } /// See the `region_obligations` field for more information. @@ -614,6 +615,7 @@ impl fmt::Display for FixupError { ), UnresolvedTy(_) => write!(f, "unconstrained type"), UnresolvedConst(_) => write!(f, "unconstrained const value"), + UnresolvedEffect(_) => write!(f, "unconstrained effect value"), } } } diff --git a/compiler/rustc_infer/src/infer/resolve.rs b/compiler/rustc_infer/src/infer/resolve.rs index 21ef2e89523f5..830d79f52b945 100644 --- a/compiler/rustc_infer/src/infer/resolve.rs +++ b/compiler/rustc_infer/src/infer/resolve.rs @@ -167,6 +167,9 @@ impl<'a, 'tcx> FallibleTypeFolder> for FullTypeResolver<'a, 'tcx> { ty::ConstKind::Infer(InferConst::Fresh(_)) => { bug!("Unexpected const in full const resolver: {:?}", c); } + ty::ConstKind::Infer(InferConst::EffectVar(evid)) => { + return Err(FixupError::UnresolvedEffect(evid)); + } _ => {} } c.try_super_fold_with(self) diff --git a/tests/crashes/119830.rs b/tests/crashes/119830.rs deleted file mode 100644 index 71becc04e1696..0000000000000 --- a/tests/crashes/119830.rs +++ /dev/null @@ -1,11 +0,0 @@ -//@ known-bug: #119830 -#![feature(effects)] -#![feature(min_specialization)] - -trait Specialize {} - -trait Foo {} - -impl const Foo for T {} - -impl const Foo for T where T: const Specialize {} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs new file mode 100644 index 0000000000000..9778217d462da --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.rs @@ -0,0 +1,24 @@ +//@ check-fail +// Fixes #119830 + +#![feature(effects)] +#![feature(min_specialization)] +#![feature(const_trait_impl)] + +trait Specialize {} + +trait Foo {} + +impl const Foo for T {} +//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` +//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] + +impl const Foo for T where T: const Specialize {} +//~^ error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` +//~| error: `const` can only be applied to `#[const_trait]` traits +//~| error: the const parameter `host` is not constrained by the impl trait, self type, or predicates [E0207] +//~| error: specialization impl does not specialize any associated items +//~| error: could not resolve generic parameters on overridden impl + +fn main() { +} diff --git a/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr new file mode 100644 index 0000000000000..d18063f8d3d88 --- /dev/null +++ b/tests/ui/rfcs/rfc-2632-const-trait-impl/effects/spec-effectvar-ice.stderr @@ -0,0 +1,69 @@ +error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` + --> $DIR/spec-effectvar-ice.rs:12:15 + | +LL | trait Foo {} + | - help: mark `Foo` as const: `#[const_trait]` +LL | +LL | impl const Foo for T {} + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: const `impl` for trait `Foo` which is not marked with `#[const_trait]` + --> $DIR/spec-effectvar-ice.rs:16:15 + | +LL | trait Foo {} + | - help: mark `Foo` as const: `#[const_trait]` +... +LL | impl const Foo for T where T: const Specialize {} + | ^^^ + | + = note: marking a trait with `#[const_trait]` ensures all default method bodies are `const` + = note: adding a non-const method body in the future would be a breaking change + +error: `const` can only be applied to `#[const_trait]` traits + --> $DIR/spec-effectvar-ice.rs:16:40 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^ + +error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates + --> $DIR/spec-effectvar-ice.rs:12:9 + | +LL | impl const Foo for T {} + | ^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error[E0207]: the const parameter `host` is not constrained by the impl trait, self type, or predicates + --> $DIR/spec-effectvar-ice.rs:16:9 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^ unconstrained const parameter + | + = note: expressions using a const parameter must map each value to a distinct output value + = note: proving the result of expressions other than the parameter are unique is not supported + +error: specialization impl does not specialize any associated items + --> $DIR/spec-effectvar-ice.rs:16:1 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: impl is a specialization of this impl + --> $DIR/spec-effectvar-ice.rs:12:1 + | +LL | impl const Foo for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: could not resolve generic parameters on overridden impl + --> $DIR/spec-effectvar-ice.rs:16:1 + | +LL | impl const Foo for T where T: const Specialize {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0207`. From 4798c20d31843b49bf3a5e891c1a3534f007ce61 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 30 May 2024 10:51:11 +1000 Subject: [PATCH 07/12] Streamline `nested` calls. `TyCtxt` impls `PpAnn` in `compiler/rustc_middle/src/hir/map/mod.rs`. We can call that impl, which then calls the one on `intravisit::Map`, instead of calling the one on `intravisit::Map` directly, avoiding a cast and extra references. --- compiler/rustc_driver_impl/src/pretty.rs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_driver_impl/src/pretty.rs b/compiler/rustc_driver_impl/src/pretty.rs index 8acba57b7a65c..31de0a747b24f 100644 --- a/compiler/rustc_driver_impl/src/pretty.rs +++ b/compiler/rustc_driver_impl/src/pretty.rs @@ -3,7 +3,6 @@ use rustc_ast as ast; use rustc_ast_pretty::pprust as pprust_ast; use rustc_errors::FatalError; -use rustc_hir as hir; use rustc_hir_pretty as pprust_hir; use rustc_middle::bug; use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty}; @@ -70,11 +69,7 @@ struct HirIdentifiedAnn<'tcx> { impl<'tcx> pprust_hir::PpAnn for HirIdentifiedAnn<'tcx> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { - pprust_hir::PpAnn::nested( - &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>), - state, - nested, - ) + self.tcx.nested(state, nested) } fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { @@ -152,8 +147,7 @@ impl<'tcx> pprust_hir::PpAnn for HirTypedAnn<'tcx> { if let pprust_hir::Nested::Body(id) = nested { self.maybe_typeck_results.set(Some(self.tcx.typeck_body(id))); } - let pp_ann = &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>); - pprust_hir::PpAnn::nested(pp_ann, state, nested); + self.tcx.nested(state, nested); self.maybe_typeck_results.set(old_maybe_typeck_results); } From 6b47c5e24d7403e7587a3aad16bcc8aed2cbbd0a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 4 Jun 2024 15:18:35 +1000 Subject: [PATCH 08/12] Remove out-of-date comment. Exhaustiveness and usefulness checking are now in `rustc_pattern_analysis`. --- compiler/rustc_mir_build/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_mir_build/src/lib.rs b/compiler/rustc_mir_build/src/lib.rs index 74600c6b12eb7..a1b8b57834911 100644 --- a/compiler/rustc_mir_build/src/lib.rs +++ b/compiler/rustc_mir_build/src/lib.rs @@ -1,6 +1,4 @@ //! Construction of MIR from HIR. -//! -//! This crate also contains the match exhaustiveness and usefulness checking. #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] From 5a5e2489c5143f9b1bea608bb10309994e6c091a Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Tue, 4 Jun 2024 15:28:09 +1000 Subject: [PATCH 09/12] Reduce `pub` exposure. A lot of errors don't need to be visible outside the crate, and some other things as well. --- .../src/build/coverageinfo/mcdc.rs | 8 +- .../rustc_mir_build/src/build/custom/parse.rs | 4 +- .../src/build/custom/parse/instruction.rs | 6 +- .../src/build/expr/as_constant.rs | 2 +- .../rustc_mir_build/src/build/expr/mod.rs | 4 +- .../rustc_mir_build/src/build/matches/util.rs | 2 +- compiler/rustc_mir_build/src/build/scope.rs | 2 +- .../rustc_mir_build/src/check_unsafety.rs | 4 +- compiler/rustc_mir_build/src/errors.rs | 518 +++++++++--------- 9 files changed, 275 insertions(+), 275 deletions(-) diff --git a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs index 7d7b7caf9ef92..f97e9ef60a297 100644 --- a/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs +++ b/compiler/rustc_mir_build/src/build/coverageinfo/mcdc.rs @@ -179,18 +179,18 @@ impl MCDCState { } } -pub struct MCDCInfoBuilder { +pub(crate) struct MCDCInfoBuilder { branch_spans: Vec, decision_spans: Vec, state: MCDCState, } impl MCDCInfoBuilder { - pub fn new() -> Self { + pub(crate) fn new() -> Self { Self { branch_spans: vec![], decision_spans: vec![], state: MCDCState::new() } } - pub fn visit_evaluated_condition( + pub(crate) fn visit_evaluated_condition( &mut self, tcx: TyCtxt<'_>, source_info: SourceInfo, @@ -243,7 +243,7 @@ impl MCDCInfoBuilder { }); } - pub fn into_done(self) -> (Vec, Vec) { + pub(crate) fn into_done(self) -> (Vec, Vec) { (self.decision_spans, self.branch_spans) } } diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs index 8bcd429b67eb2..9607022c6df04 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse.rs @@ -91,7 +91,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { } } - pub fn parse_args(&mut self, params: &IndexSlice>) -> PResult<()> { + pub(crate) fn parse_args(&mut self, params: &IndexSlice>) -> PResult<()> { for param in params.iter() { let (var, span) = { let pat = param.pat.as_ref().unwrap(); @@ -149,7 +149,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { /// /// This allows us to easily parse the basic blocks declarations, local declarations, and /// basic block definitions in order. - pub fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> { + pub(crate) fn parse_body(&mut self, expr_id: ExprId) -> PResult<()> { let body = parse_by_kind!(self, expr_id, _, "whole body", ExprKind::Block { block } => self.thir[*block].expr.unwrap(), ); 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 de748b9c85d17..b1a305efa4c68 100644 --- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs +++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs @@ -12,7 +12,7 @@ use crate::build::expr::as_constant::as_constant_inner; use super::{parse_by_kind, PResult, ParseCtxt}; impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { - pub fn parse_statement(&self, expr_id: ExprId) -> PResult> { + pub(crate) fn parse_statement(&self, expr_id: ExprId) -> PResult> { parse_by_kind!(self, expr_id, _, "statement", @call(mir_storage_live, args) => { Ok(StatementKind::StorageLive(self.parse_local(args[0])?)) @@ -46,7 +46,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ) } - pub fn parse_terminator(&self, expr_id: ExprId) -> PResult> { + pub(crate) fn parse_terminator(&self, expr_id: ExprId) -> PResult> { parse_by_kind!(self, expr_id, expr, "terminator", @call(mir_return, _args) => { Ok(TerminatorKind::Return) @@ -261,7 +261,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> { ) } - pub fn parse_operand(&self, expr_id: ExprId) -> PResult> { + pub(crate) fn parse_operand(&self, expr_id: ExprId) -> PResult> { parse_by_kind!(self, expr_id, expr, "operand", @call(mir_move, args) => self.parse_place(args[0]).map(Operand::Move), @call(mir_static, args) => self.parse_static(args[0]), 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 b4dd423f344ab..f7229326c541d 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs @@ -39,7 +39,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } } -pub fn as_constant_inner<'tcx>( +pub(crate) fn as_constant_inner<'tcx>( expr: &Expr<'tcx>, push_cuta: impl FnMut(&Box>) -> Option, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_mir_build/src/build/expr/mod.rs b/compiler/rustc_mir_build/src/build/expr/mod.rs index dfe85b858cd0d..3de43a3370f31 100644 --- a/compiler/rustc_mir_build/src/build/expr/mod.rs +++ b/compiler/rustc_mir_build/src/build/expr/mod.rs @@ -62,9 +62,9 @@ pub(crate) mod as_constant; mod as_operand; -pub mod as_place; +pub(crate) mod as_place; mod as_rvalue; mod as_temp; -pub mod category; +pub(crate) mod category; mod into; mod stmt; diff --git a/compiler/rustc_mir_build/src/build/matches/util.rs b/compiler/rustc_mir_build/src/build/matches/util.rs index 770f689724af0..50f4ca2d819d3 100644 --- a/compiler/rustc_mir_build/src/build/matches/util.rs +++ b/compiler/rustc_mir_build/src/build/matches/util.rs @@ -456,7 +456,7 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> { } #[must_use] -pub fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind { +pub(crate) fn ref_pat_borrow_kind(ref_mutability: Mutability) -> BorrowKind { match ref_mutability { Mutability::Mut => BorrowKind::Mut { kind: MutBorrowKind::Default }, Mutability::Not => BorrowKind::Shared, diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs index c7850c7aea872..5b6de39bb2e78 100644 --- a/compiler/rustc_mir_build/src/build/scope.rs +++ b/compiler/rustc_mir_build/src/build/scope.rs @@ -97,7 +97,7 @@ use rustc_span::{Span, DUMMY_SP}; use tracing::{debug, instrument}; #[derive(Debug)] -pub struct Scopes<'tcx> { +pub(crate) struct Scopes<'tcx> { scopes: Vec, /// The current set of breakable scopes. See module comment for more details. diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs index 24098282d93b1..659ae1724603a 100644 --- a/compiler/rustc_mir_build/src/check_unsafety.rs +++ b/compiler/rustc_mir_build/src/check_unsafety.rs @@ -597,7 +597,7 @@ enum UnsafeOpKind { use UnsafeOpKind::*; impl UnsafeOpKind { - pub fn emit_unsafe_op_in_unsafe_fn_lint( + fn emit_unsafe_op_in_unsafe_fn_lint( &self, tcx: TyCtxt<'_>, hir_id: HirId, @@ -737,7 +737,7 @@ impl UnsafeOpKind { } } - pub fn emit_requires_unsafe_err( + fn emit_requires_unsafe_err( &self, tcx: TyCtxt<'_>, span: Span, diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs index d7ed4f57e5965..cf324c03dc9f2 100644 --- a/compiler/rustc_mir_build/src/errors.rs +++ b/compiler/rustc_mir_build/src/errors.rs @@ -13,111 +13,111 @@ use rustc_span::Span; #[derive(LintDiagnostic)] #[diag(mir_build_unconditional_recursion)] #[help] -pub struct UnconditionalRecursion { +pub(crate) struct UnconditionalRecursion { #[label] - pub span: Span, + pub(crate) span: Span, #[label(mir_build_unconditional_recursion_call_site_label)] - pub call_sites: Vec, + pub(crate) call_sites: Vec, } #[derive(LintDiagnostic)] #[diag(mir_build_call_to_deprecated_safe_fn_requires_unsafe)] -pub struct CallToDeprecatedSafeFnRequiresUnsafe { +pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafe { #[label] - pub span: Span, - pub function: String, + pub(crate) span: Span, + pub(crate) function: String, #[subdiagnostic] - pub sub: CallToDeprecatedSafeFnRequiresUnsafeSub, + pub(crate) sub: CallToDeprecatedSafeFnRequiresUnsafeSub, } #[derive(Subdiagnostic)] #[multipart_suggestion(mir_build_suggestion, applicability = "machine-applicable")] -pub struct CallToDeprecatedSafeFnRequiresUnsafeSub { +pub(crate) struct CallToDeprecatedSafeFnRequiresUnsafeSub { #[suggestion_part(code = "unsafe {{ ")] - pub left: Span, + pub(crate) left: Span, #[suggestion_part(code = " }}")] - pub right: Span, + pub(crate) right: Span, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafe { #[label] - pub span: Span, - pub function: String, + pub(crate) span: Span, + pub(crate) function: String, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { +pub(crate) struct UnsafeOpInUnsafeFnCallToUnsafeFunctionRequiresUnsafeNameless { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_inline_assembly_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnUseOfInlineAssemblyRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_initializing_type_with_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnInitializingTypeWithRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_mutable_static_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnUseOfMutableStaticRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_extern_static_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnUseOfExternStaticRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnDerefOfRawPointerRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_union_field_requires_unsafe, code = E0133)] #[note] -pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] @@ -126,11 +126,11 @@ pub struct UnsafeOpInUnsafeFnAccessToUnionFieldRequiresUnsafe { code = E0133 )] #[note] -pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] @@ -138,63 +138,63 @@ pub struct UnsafeOpInUnsafeFnMutationOfLayoutConstrainedFieldRequiresUnsafe { mir_build_unsafe_op_in_unsafe_fn_borrow_of_layout_constrained_field_requires_unsafe, code = E0133, )] -pub struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnBorrowOfLayoutConstrainedFieldRequiresUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(LintDiagnostic)] #[diag(mir_build_unsafe_op_in_unsafe_fn_call_to_fn_with_requires_unsafe, code = E0133)] #[help] -pub struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { +pub(crate) struct UnsafeOpInUnsafeFnCallToFunctionWithRequiresUnsafe { #[label] - pub span: Span, - pub function: String, - pub missing_target_features: DiagArgValue, - pub missing_target_features_count: usize, + pub(crate) span: Span, + pub(crate) function: String, + pub(crate) missing_target_features: DiagArgValue, + pub(crate) missing_target_features_count: usize, #[note] - pub note: Option<()>, - pub build_target_features: DiagArgValue, - pub build_target_features_count: usize, + pub(crate) note: Option<()>, + pub(crate) build_target_features: DiagArgValue, + pub(crate) build_target_features_count: usize, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe, code = E0133)] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafe { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafe { #[primary_span] #[label] - pub span: Span, - pub function: String, + pub(crate) span: Span, + pub(crate) function: String, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_nameless, code = E0133)] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafeNameless { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNameless { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_unsafe_fn_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, - pub function: String, + pub(crate) span: Span, + pub(crate) function: String, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -203,45 +203,45 @@ pub struct CallToUnsafeFunctionRequiresUnsafeUnsafeOpInUnsafeFnAllowed { code = E0133 )] #[note] -pub struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { +pub(crate) struct CallToUnsafeFunctionRequiresUnsafeNamelessUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_inline_assembly_requires_unsafe, code = E0133)] #[note] -pub struct UseOfInlineAssemblyRequiresUnsafe { +pub(crate) struct UseOfInlineAssemblyRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_inline_assembly_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct UseOfInlineAssemblyRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_initializing_type_with_requires_unsafe, code = E0133)] #[note] -pub struct InitializingTypeWithRequiresUnsafe { +pub(crate) struct InitializingTypeWithRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -250,111 +250,111 @@ pub struct InitializingTypeWithRequiresUnsafe { code = E0133 )] #[note] -pub struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct InitializingTypeWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_mutable_static_requires_unsafe, code = E0133)] #[note] -pub struct UseOfMutableStaticRequiresUnsafe { +pub(crate) struct UseOfMutableStaticRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_mutable_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct UseOfMutableStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_extern_static_requires_unsafe, code = E0133)] #[note] -pub struct UseOfExternStaticRequiresUnsafe { +pub(crate) struct UseOfExternStaticRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_extern_static_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct UseOfExternStaticRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_deref_raw_pointer_requires_unsafe, code = E0133)] #[note] -pub struct DerefOfRawPointerRequiresUnsafe { +pub(crate) struct DerefOfRawPointerRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_deref_raw_pointer_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct DerefOfRawPointerRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_union_field_requires_unsafe, code = E0133)] #[note] -pub struct AccessToUnionFieldRequiresUnsafe { +pub(crate) struct AccessToUnionFieldRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_union_field_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[note] -pub struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct AccessToUnionFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_mutation_of_layout_constrained_field_requires_unsafe, code = E0133)] #[note] -pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -363,23 +363,23 @@ pub struct MutationOfLayoutConstrainedFieldRequiresUnsafe { code = E0133 )] #[note] -pub struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct MutationOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_borrow_of_layout_constrained_field_requires_unsafe, code = E0133)] #[note] -pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { +pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] @@ -388,60 +388,60 @@ pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafe { code = E0133 )] #[note] -pub struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct BorrowOfLayoutConstrainedFieldRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_fn_with_requires_unsafe, code = E0133)] #[help] -pub struct CallToFunctionWithRequiresUnsafe { +pub(crate) struct CallToFunctionWithRequiresUnsafe { #[primary_span] #[label] - pub span: Span, - pub function: String, - pub missing_target_features: DiagArgValue, - pub missing_target_features_count: usize, + pub(crate) span: Span, + pub(crate) function: String, + pub(crate) missing_target_features: DiagArgValue, + pub(crate) missing_target_features_count: usize, #[note] - pub note: Option<()>, - pub build_target_features: DiagArgValue, - pub build_target_features_count: usize, + pub(crate) note: Option<()>, + pub(crate) build_target_features: DiagArgValue, + pub(crate) build_target_features_count: usize, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Diagnostic)] #[diag(mir_build_call_to_fn_with_requires_unsafe_unsafe_op_in_unsafe_fn_allowed, code = E0133)] #[help] -pub struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { +pub(crate) struct CallToFunctionWithRequiresUnsafeUnsafeOpInUnsafeFnAllowed { #[primary_span] #[label] - pub span: Span, - pub function: String, - pub missing_target_features: DiagArgValue, - pub missing_target_features_count: usize, + pub(crate) span: Span, + pub(crate) function: String, + pub(crate) missing_target_features: DiagArgValue, + pub(crate) missing_target_features_count: usize, #[note] - pub note: Option<()>, - pub build_target_features: DiagArgValue, - pub build_target_features_count: usize, + pub(crate) note: Option<()>, + pub(crate) build_target_features: DiagArgValue, + pub(crate) build_target_features_count: usize, #[subdiagnostic] - pub unsafe_not_inherited_note: Option, + pub(crate) unsafe_not_inherited_note: Option, } #[derive(Subdiagnostic)] #[label(mir_build_unsafe_not_inherited)] -pub struct UnsafeNotInheritedNote { +pub(crate) struct UnsafeNotInheritedNote { #[primary_span] - pub span: Span, + pub(crate) span: Span, } -pub struct UnsafeNotInheritedLintNote { - pub signature_span: Span, - pub body_span: Span, +pub(crate) struct UnsafeNotInheritedLintNote { + pub(crate) signature_span: Span, + pub(crate) body_span: Span, } impl Subdiagnostic for UnsafeNotInheritedLintNote { @@ -463,15 +463,15 @@ impl Subdiagnostic for UnsafeNotInheritedLintNote { #[derive(LintDiagnostic)] #[diag(mir_build_unused_unsafe)] -pub struct UnusedUnsafe { +pub(crate) struct UnusedUnsafe { #[label] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub enclosing: Option, + pub(crate) enclosing: Option, } #[derive(Subdiagnostic)] -pub enum UnusedUnsafeEnclosing { +pub(crate) enum UnusedUnsafeEnclosing { #[label(mir_build_unused_unsafe_enclosing_block_label)] Block { #[primary_span] @@ -480,10 +480,10 @@ pub enum UnusedUnsafeEnclosing { } pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> { - pub cx: &'m RustcPatCtxt<'p, 'tcx>, - pub scrut_span: Span, - pub braces_span: Option, - pub ty: Ty<'tcx>, + pub(crate) cx: &'m RustcPatCtxt<'p, 'tcx>, + pub(crate) scrut_span: Span, + pub(crate) braces_span: Option, + pub(crate) ty: Ty<'tcx>, } impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNotEmpty<'_, '_, '_> { @@ -552,197 +552,197 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo #[derive(Subdiagnostic)] #[note(mir_build_non_exhaustive_match_all_arms_guarded)] -pub struct NonExhaustiveMatchAllArmsGuarded; +pub(crate) struct NonExhaustiveMatchAllArmsGuarded; #[derive(Diagnostic)] #[diag(mir_build_static_in_pattern, code = E0158)] -pub struct StaticInPattern { +pub(crate) struct StaticInPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_assoc_const_in_pattern, code = E0158)] -pub struct AssocConstInPattern { +pub(crate) struct AssocConstInPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_const_param_in_pattern, code = E0158)] -pub struct ConstParamInPattern { +pub(crate) struct ConstParamInPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_non_const_path, code = E0080)] -pub struct NonConstPath { +pub(crate) struct NonConstPath { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(LintDiagnostic)] #[diag(mir_build_unreachable_pattern)] -pub struct UnreachablePattern { +pub(crate) struct UnreachablePattern { #[label] - pub span: Option, + pub(crate) span: Option, #[label(mir_build_catchall_label)] - pub catchall: Option, + pub(crate) catchall: Option, } #[derive(Diagnostic)] #[diag(mir_build_const_pattern_depends_on_generic_parameter)] -pub struct ConstPatternDependsOnGenericParameter { +pub(crate) struct ConstPatternDependsOnGenericParameter { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_could_not_eval_const_pattern)] -pub struct CouldNotEvalConstPattern { +pub(crate) struct CouldNotEvalConstPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_lower_range_bound_must_be_less_than_or_equal_to_upper, code = E0030)] -pub struct LowerRangeBoundMustBeLessThanOrEqualToUpper { +pub(crate) struct LowerRangeBoundMustBeLessThanOrEqualToUpper { #[primary_span] #[label] - pub span: Span, + pub(crate) span: Span, #[note(mir_build_teach_note)] - pub teach: Option<()>, + pub(crate) teach: Option<()>, } #[derive(Diagnostic)] #[diag(mir_build_literal_in_range_out_of_bounds)] -pub struct LiteralOutOfRange<'tcx> { +pub(crate) struct LiteralOutOfRange<'tcx> { #[primary_span] #[label] - pub span: Span, - pub ty: Ty<'tcx>, - pub min: i128, - pub max: u128, + pub(crate) span: Span, + pub(crate) ty: Ty<'tcx>, + pub(crate) min: i128, + pub(crate) max: u128, } #[derive(Diagnostic)] #[diag(mir_build_lower_range_bound_must_be_less_than_upper, code = E0579)] -pub struct LowerRangeBoundMustBeLessThanUpper { +pub(crate) struct LowerRangeBoundMustBeLessThanUpper { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(LintDiagnostic)] #[diag(mir_build_leading_irrefutable_let_patterns)] #[note] #[help] -pub struct LeadingIrrefutableLetPatterns { - pub count: usize, +pub(crate) struct LeadingIrrefutableLetPatterns { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_trailing_irrefutable_let_patterns)] #[note] #[help] -pub struct TrailingIrrefutableLetPatterns { - pub count: usize, +pub(crate) struct TrailingIrrefutableLetPatterns { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_bindings_with_variant_name, code = E0170)] -pub struct BindingsWithVariantName { +pub(crate) struct BindingsWithVariantName { #[suggestion(code = "{ty_path}::{name}", applicability = "machine-applicable")] - pub suggestion: Option, - pub ty_path: String, - pub name: Symbol, + pub(crate) suggestion: Option, + pub(crate) ty_path: String, + pub(crate) name: Symbol, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_if_let)] #[note] #[help] -pub struct IrrefutableLetPatternsIfLet { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsIfLet { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_if_let_guard)] #[note] #[help] -pub struct IrrefutableLetPatternsIfLetGuard { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsIfLetGuard { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_let_else)] #[note] #[help] -pub struct IrrefutableLetPatternsLetElse { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsLetElse { + pub(crate) count: usize, } #[derive(LintDiagnostic)] #[diag(mir_build_irrefutable_let_patterns_while_let)] #[note] #[help] -pub struct IrrefutableLetPatternsWhileLet { - pub count: usize, +pub(crate) struct IrrefutableLetPatternsWhileLet { + pub(crate) count: usize, } #[derive(Diagnostic)] #[diag(mir_build_borrow_of_moved_value)] -pub struct BorrowOfMovedValue<'tcx> { +pub(crate) struct BorrowOfMovedValue<'tcx> { #[primary_span] #[label] #[label(mir_build_occurs_because_label)] - pub binding_span: Span, + pub(crate) binding_span: Span, #[label(mir_build_value_borrowed_label)] - pub conflicts_ref: Vec, - pub name: Symbol, - pub ty: Ty<'tcx>, + pub(crate) conflicts_ref: Vec, + pub(crate) name: Symbol, + pub(crate) ty: Ty<'tcx>, #[suggestion(code = "ref ", applicability = "machine-applicable")] - pub suggest_borrowing: Option, + pub(crate) suggest_borrowing: Option, } #[derive(Diagnostic)] #[diag(mir_build_multiple_mut_borrows)] -pub struct MultipleMutBorrows { +pub(crate) struct MultipleMutBorrows { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Diagnostic)] #[diag(mir_build_already_borrowed)] -pub struct AlreadyBorrowed { +pub(crate) struct AlreadyBorrowed { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Diagnostic)] #[diag(mir_build_already_mut_borrowed)] -pub struct AlreadyMutBorrowed { +pub(crate) struct AlreadyMutBorrowed { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Diagnostic)] #[diag(mir_build_moved_while_borrowed)] -pub struct MovedWhileBorrowed { +pub(crate) struct MovedWhileBorrowed { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub occurrences: Vec, + pub(crate) occurrences: Vec, } #[derive(Subdiagnostic)] -pub enum Conflict { +pub(crate) enum Conflict { #[label(mir_build_mutable_borrow)] Mut { #[primary_span] @@ -765,118 +765,118 @@ pub enum Conflict { #[derive(Diagnostic)] #[diag(mir_build_union_pattern)] -pub struct UnionPattern { +pub(crate) struct UnionPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_type_not_structural)] #[note(mir_build_type_not_structural_tip)] #[note(mir_build_type_not_structural_more_info)] -pub struct TypeNotStructural<'tcx> { +pub(crate) struct TypeNotStructural<'tcx> { #[primary_span] - pub span: Span, - pub non_sm_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_sm_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_non_partial_eq_match)] -pub struct TypeNotPartialEq<'tcx> { +pub(crate) struct TypeNotPartialEq<'tcx> { #[primary_span] - pub span: Span, - pub non_peq_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_peq_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_invalid_pattern)] -pub struct InvalidPattern<'tcx> { +pub(crate) struct InvalidPattern<'tcx> { #[primary_span] - pub span: Span, - pub non_sm_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_sm_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_unsized_pattern)] -pub struct UnsizedPattern<'tcx> { +pub(crate) struct UnsizedPattern<'tcx> { #[primary_span] - pub span: Span, - pub non_sm_ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) non_sm_ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_nan_pattern)] #[note] #[help] -pub struct NaNPattern { +pub(crate) struct NaNPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_pointer_pattern)] -pub struct PointerPattern { +pub(crate) struct PointerPattern { #[primary_span] - pub span: Span, + pub(crate) span: Span, } #[derive(Diagnostic)] #[diag(mir_build_non_empty_never_pattern)] #[note] -pub struct NonEmptyNeverPattern<'tcx> { +pub(crate) struct NonEmptyNeverPattern<'tcx> { #[primary_span] #[label] - pub span: Span, - pub ty: Ty<'tcx>, + pub(crate) span: Span, + pub(crate) ty: Ty<'tcx>, } #[derive(Diagnostic)] #[diag(mir_build_exceeds_mcdc_condition_limit)] pub(crate) struct MCDCExceedsConditionLimit { #[primary_span] - pub span: Span, - pub num_conditions: usize, - pub max_conditions: usize, + pub(crate) span: Span, + pub(crate) num_conditions: usize, + pub(crate) max_conditions: usize, } #[derive(Diagnostic)] #[diag(mir_build_pattern_not_covered, code = E0005)] pub(crate) struct PatternNotCovered<'s, 'tcx> { #[primary_span] - pub span: Span, - pub origin: &'s str, + pub(crate) span: Span, + pub(crate) origin: &'s str, #[subdiagnostic] - pub uncovered: Uncovered<'tcx>, + pub(crate) uncovered: Uncovered<'tcx>, #[subdiagnostic] - pub inform: Option, + pub(crate) inform: Option, #[subdiagnostic] - pub interpreted_as_const: Option, + pub(crate) interpreted_as_const: Option, #[subdiagnostic] - pub adt_defined_here: Option>, + pub(crate) adt_defined_here: Option>, #[note(mir_build_privately_uninhabited)] - pub witness_1_is_privately_uninhabited: Option<()>, + pub(crate) witness_1_is_privately_uninhabited: Option<()>, #[note(mir_build_pattern_ty)] - pub _p: (), - pub pattern_ty: Ty<'tcx>, + pub(crate) _p: (), + pub(crate) pattern_ty: Ty<'tcx>, #[subdiagnostic] - pub let_suggestion: Option, + pub(crate) let_suggestion: Option, #[subdiagnostic] - pub misc_suggestion: Option, + pub(crate) misc_suggestion: Option, } #[derive(Subdiagnostic)] #[note(mir_build_inform_irrefutable)] #[note(mir_build_more_information)] -pub struct Inform; +pub(crate) struct Inform; -pub struct AdtDefinedHere<'tcx> { - pub adt_def_span: Span, - pub ty: Ty<'tcx>, - pub variants: Vec, +pub(crate) struct AdtDefinedHere<'tcx> { + pub(crate) adt_def_span: Span, + pub(crate) ty: Ty<'tcx>, + pub(crate) variants: Vec, } -pub struct Variant { - pub span: Span, +pub(crate) struct Variant { + pub(crate) span: Span, } impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> { @@ -903,14 +903,14 @@ impl<'tcx> Subdiagnostic for AdtDefinedHere<'tcx> { applicability = "maybe-incorrect" )] #[label(mir_build_confused)] -pub struct InterpretedAsConst { +pub(crate) struct InterpretedAsConst { #[primary_span] - pub span: Span, - pub variable: String, + pub(crate) span: Span, + pub(crate) variable: String, } #[derive(Subdiagnostic)] -pub enum SuggestLet { +pub(crate) enum SuggestLet { #[multipart_suggestion(mir_build_suggest_if_let, applicability = "has-placeholders")] If { #[suggestion_part(code = "if ")] @@ -932,7 +932,7 @@ pub enum SuggestLet { } #[derive(Subdiagnostic)] -pub enum MiscPatternSuggestion { +pub(crate) enum MiscPatternSuggestion { #[suggestion( mir_build_suggest_attempted_int_lit, code = "_", @@ -946,15 +946,15 @@ pub enum MiscPatternSuggestion { #[derive(Diagnostic)] #[diag(mir_build_rustc_box_attribute_error)] -pub struct RustcBoxAttributeError { +pub(crate) struct RustcBoxAttributeError { #[primary_span] - pub span: Span, + pub(crate) span: Span, #[subdiagnostic] - pub reason: RustcBoxAttrReason, + pub(crate) reason: RustcBoxAttrReason, } #[derive(Subdiagnostic)] -pub enum RustcBoxAttrReason { +pub(crate) enum RustcBoxAttrReason { #[note(mir_build_attributes)] Attributes, #[note(mir_build_not_box)] @@ -965,13 +965,13 @@ pub enum RustcBoxAttrReason { #[derive(LintDiagnostic)] #[diag(mir_build_rust_2024_incompatible_pat)] -pub struct Rust2024IncompatiblePat { +pub(crate) struct Rust2024IncompatiblePat { #[subdiagnostic] - pub sugg: Rust2024IncompatiblePatSugg, + pub(crate) sugg: Rust2024IncompatiblePatSugg, } -pub struct Rust2024IncompatiblePatSugg { - pub suggestion: Vec<(Span, String)>, +pub(crate) struct Rust2024IncompatiblePatSugg { + pub(crate) suggestion: Vec<(Span, String)>, } impl Subdiagnostic for Rust2024IncompatiblePatSugg { From f076dec33622904821b7829ba759da9c610d1451 Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 4 Jun 2024 02:24:57 +0100 Subject: [PATCH 10/12] Downsize `ty::Expr` --- compiler/rustc_middle/src/ty/consts.rs | 4 +- compiler/rustc_middle/src/ty/consts/kind.rs | 125 +++++++++++++++++- compiler/rustc_middle/src/ty/flags.rs | 21 +-- compiler/rustc_middle/src/ty/mod.rs | 2 +- compiler/rustc_middle/src/ty/print/pretty.rs | 102 ++++++-------- compiler/rustc_middle/src/ty/relate.rs | 52 ++------ .../rustc_middle/src/ty/structural_impls.rs | 38 ++++-- compiler/rustc_middle/src/ty/walk.rs | 19 +-- compiler/rustc_ty_utils/src/consts.rs | 33 +++-- 9 files changed, 233 insertions(+), 163 deletions(-) diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs index 6416bbbe889cb..384a4e7009d84 100644 --- a/compiler/rustc_middle/src/ty/consts.rs +++ b/compiler/rustc_middle/src/ty/consts.rs @@ -24,7 +24,7 @@ pub type ConstKind<'tcx> = ir::ConstKind>; pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst>; #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(ConstKind<'_>, 32); +rustc_data_structures::static_assert_size!(ConstKind<'_>, 24); /// Use this rather than `ConstData`, whenever possible. #[derive(Copy, Clone, PartialEq, Eq, Hash, HashStable)] @@ -58,7 +58,7 @@ pub struct ConstData<'tcx> { } #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(ConstData<'_>, 40); +rustc_data_structures::static_assert_size!(ConstData<'_>, 32); impl<'tcx> Const<'tcx> { #[inline] diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs index d7ae050ed4d02..5f29acf5ed274 100644 --- a/compiler/rustc_middle/src/ty/consts/kind.rs +++ b/compiler/rustc_middle/src/ty/consts/kind.rs @@ -1,7 +1,7 @@ use super::Const; use crate::mir; use crate::ty::abstract_const::CastKind; -use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt}; +use crate::ty::{self, visit::TypeVisitableExt as _, Ty, TyCtxt}; use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable}; #[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)] @@ -40,14 +40,125 @@ impl<'tcx> ty::UnevaluatedConst<'tcx> { } } +#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)] +#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] +pub enum ExprKind { + Binop(mir::BinOp), + UnOp(mir::UnOp), + FunctionCall, + Cast(CastKind), +} #[derive(Copy, Clone, Eq, PartialEq, Hash)] #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)] -pub enum Expr<'tcx> { - Binop(mir::BinOp, Const<'tcx>, Const<'tcx>), - UnOp(mir::UnOp, Const<'tcx>), - FunctionCall(Const<'tcx>, &'tcx List>), - Cast(CastKind, Const<'tcx>, Ty<'tcx>), +pub struct Expr<'tcx> { + pub kind: ExprKind, + args: ty::GenericArgsRef<'tcx>, +} +impl<'tcx> Expr<'tcx> { + pub fn new_binop( + tcx: TyCtxt<'tcx>, + binop: mir::BinOp, + lhs_ty: Ty<'tcx>, + rhs_ty: Ty<'tcx>, + lhs_ct: Const<'tcx>, + rhs_ct: Const<'tcx>, + ) -> Self { + let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>( + [lhs_ty.into(), rhs_ty.into(), lhs_ct.into(), rhs_ct.into()].into_iter(), + ); + + Self { kind: ExprKind::Binop(binop), args } + } + + pub fn binop_args(self) -> (Ty<'tcx>, Ty<'tcx>, Const<'tcx>, Const<'tcx>) { + assert!(matches!(self.kind, ExprKind::Binop(_))); + + match self.args().as_slice() { + [lhs_ty, rhs_ty, lhs_ct, rhs_ct] => ( + lhs_ty.expect_ty(), + rhs_ty.expect_ty(), + lhs_ct.expect_const(), + rhs_ct.expect_const(), + ), + _ => bug!("Invalid args for `Binop` expr {self:?}"), + } + } + + pub fn new_unop(tcx: TyCtxt<'tcx>, unop: mir::UnOp, ty: Ty<'tcx>, ct: Const<'tcx>) -> Self { + let args = + tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>([ty.into(), ct.into()].into_iter()); + + Self { kind: ExprKind::UnOp(unop), args } + } + + pub fn unop_args(self) -> (Ty<'tcx>, Const<'tcx>) { + assert!(matches!(self.kind, ExprKind::UnOp(_))); + + match self.args().as_slice() { + [ty, ct] => (ty.expect_ty(), ct.expect_const()), + _ => bug!("Invalid args for `UnOp` expr {self:?}"), + } + } + + pub fn new_call( + tcx: TyCtxt<'tcx>, + func_ty: Ty<'tcx>, + func_expr: Const<'tcx>, + arguments: impl Iterator>, + ) -> Self { + let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>( + [func_ty.into(), func_expr.into()].into_iter().chain(arguments.map(|ct| ct.into())), + ); + + Self { kind: ExprKind::FunctionCall, args } + } + + pub fn call_args(self) -> (Ty<'tcx>, Const<'tcx>, impl Iterator>) { + assert!(matches!(self.kind, ExprKind::FunctionCall)); + + match self.args().as_slice() { + [func_ty, func, rest @ ..] => ( + func_ty.expect_ty(), + func.expect_const(), + rest.iter().map(|arg| arg.expect_const()), + ), + _ => bug!("Invalid args for `Call` expr {self:?}"), + } + } + + pub fn new_cast( + tcx: TyCtxt<'tcx>, + cast: CastKind, + value_ty: Ty<'tcx>, + value: Const<'tcx>, + to_ty: Ty<'tcx>, + ) -> Self { + let args = tcx.mk_args_from_iter::<_, ty::GenericArg<'tcx>>( + [value_ty.into(), value.into(), to_ty.into()].into_iter(), + ); + + Self { kind: ExprKind::Cast(cast), args } + } + + pub fn cast_args(self) -> (Ty<'tcx>, Const<'tcx>, Ty<'tcx>) { + assert!(matches!(self.kind, ExprKind::Cast(_))); + + match self.args().as_slice() { + [value_ty, value, to_ty] => { + (value_ty.expect_ty(), value.expect_const(), to_ty.expect_ty()) + } + _ => bug!("Invalid args for `Cast` expr {self:?}"), + } + } + + pub fn new(kind: ExprKind, args: ty::GenericArgsRef<'tcx>) -> Self { + Self { kind, args } + } + + pub fn args(&self) -> ty::GenericArgsRef<'tcx> { + self.args + } } #[cfg(target_pointer_width = "64")] -rustc_data_structures::static_assert_size!(Expr<'_>, 24); +rustc_data_structures::static_assert_size!(Expr<'_>, 16); diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 4de7d532c967c..93a51d3a33408 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -374,26 +374,7 @@ impl FlagComputation { self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE); } ty::ConstKind::Value(_) => {} - ty::ConstKind::Expr(e) => { - use ty::Expr; - match e { - Expr::Binop(_, l, r) => { - self.add_const(l); - self.add_const(r); - } - Expr::UnOp(_, v) => self.add_const(v), - Expr::FunctionCall(f, args) => { - self.add_const(f); - for arg in args { - self.add_const(arg); - } - } - Expr::Cast(_, c, t) => { - self.add_ty(t); - self.add_const(c); - } - } - } + ty::ConstKind::Expr(e) => self.add_args(e.args()), ty::ConstKind::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2643ce976ded1..714224fc96545 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -87,7 +87,7 @@ pub use self::closure::{ CAPTURE_STRUCT_LOCAL, }; pub use self::consts::{ - Const, ConstData, ConstInt, ConstKind, Expr, ScalarInt, UnevaluatedConst, ValTree, + Const, ConstData, ConstInt, ConstKind, Expr, ExprKind, ScalarInt, UnevaluatedConst, ValTree, }; pub use self::context::{ tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift, diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 8fb4367d3b586..80d5b7445d098 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1533,8 +1533,10 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { print_ty: bool, ) -> Result<(), PrintError> { define_scoped_cx!(self); - match expr { - Expr::Binop(op, c1, c2) => { + match expr.kind { + ty::ExprKind::Binop(op) => { + let (_, _, c1, c2) = expr.binop_args(); + let precedence = |binop: rustc_middle::mir::BinOp| { use rustc_ast::util::parser::AssocOp; AssocOp::from_ast_binop(binop.to_hir_binop().into()).precedence() @@ -1543,22 +1545,26 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { let formatted_op = op.to_hir_binop().as_str(); let (lhs_parenthesized, rhs_parenthesized) = match (c1.kind(), c2.kind()) { ( - ty::ConstKind::Expr(Expr::Binop(lhs_op, _, _)), - ty::ConstKind::Expr(Expr::Binop(rhs_op, _, _)), + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }), + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }), ) => (precedence(lhs_op) < op_precedence, precedence(rhs_op) < op_precedence), - (ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), ty::ConstKind::Expr(_)) => { - (precedence(lhs_op) < op_precedence, true) - } - (ty::ConstKind::Expr(_), ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => { - (true, precedence(rhs_op) < op_precedence) - } + ( + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }), + ty::ConstKind::Expr(_), + ) => (precedence(lhs_op) < op_precedence, true), + ( + ty::ConstKind::Expr(_), + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }), + ) => (true, precedence(rhs_op) < op_precedence), (ty::ConstKind::Expr(_), ty::ConstKind::Expr(_)) => (true, true), - (ty::ConstKind::Expr(Expr::Binop(lhs_op, ..)), _) => { - (precedence(lhs_op) < op_precedence, false) - } - (_, ty::ConstKind::Expr(Expr::Binop(rhs_op, ..))) => { - (false, precedence(rhs_op) < op_precedence) - } + ( + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(lhs_op), .. }), + _, + ) => (precedence(lhs_op) < op_precedence, false), + ( + _, + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::Binop(rhs_op), .. }), + ) => (false, precedence(rhs_op) < op_precedence), (ty::ConstKind::Expr(_), _) => (true, false), (_, ty::ConstKind::Expr(_)) => (false, true), _ => (false, false), @@ -1574,7 +1580,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { rhs_parenthesized, )?; } - Expr::UnOp(op, ct) => { + ty::ExprKind::UnOp(op) => { + let (_, ct) = expr.unop_args(); + use rustc_middle::mir::UnOp; let formatted_op = match op { UnOp::Not => "!", @@ -1583,7 +1591,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { }; let parenthesized = match ct.kind() { _ if op == UnOp::PtrMetadata => true, - ty::ConstKind::Expr(Expr::UnOp(c_op, ..)) => c_op != op, + ty::ConstKind::Expr(ty::Expr { kind: ty::ExprKind::UnOp(c_op), .. }) => { + c_op != op + } ty::ConstKind::Expr(_) => true, _ => false, }; @@ -1593,61 +1603,37 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write { parenthesized, )? } - Expr::FunctionCall(fn_def, fn_args) => { - use ty::TyKind; - match fn_def.ty().kind() { - TyKind::FnDef(def_id, gen_args) => { - p!(print_value_path(*def_id, gen_args), "("); - if print_ty { - let tcx = self.tcx(); - let sig = tcx.fn_sig(def_id).instantiate(tcx, gen_args).skip_binder(); - - let mut args_with_ty = fn_args.iter().map(|ct| (ct, ct.ty())); - let output_ty = sig.output(); - - if let Some((ct, ty)) = args_with_ty.next() { - self.typed_value( - |this| this.pretty_print_const(ct, print_ty), - |this| this.pretty_print_type(ty), - ": ", - )?; - for (ct, ty) in args_with_ty { - p!(", "); - self.typed_value( - |this| this.pretty_print_const(ct, print_ty), - |this| this.pretty_print_type(ty), - ": ", - )?; - } - } - p!(write(") -> {output_ty}")); - } else { - p!(comma_sep(fn_args.iter()), ")"); - } - } - _ => bug!("unexpected type of fn def"), - } + ty::ExprKind::FunctionCall => { + let (_, fn_def, fn_args) = expr.call_args(); + + write!(self, "(")?; + self.pretty_print_const(fn_def, print_ty)?; + p!(")(", comma_sep(fn_args), ")"); } - Expr::Cast(kind, ct, ty) => { + ty::ExprKind::Cast(kind) => { + let (_, value, to_ty) = expr.cast_args(); + use ty::abstract_const::CastKind; if kind == CastKind::As || (kind == CastKind::Use && self.should_print_verbose()) { - let parenthesized = match ct.kind() { - ty::ConstKind::Expr(Expr::Cast(_, _, _)) => false, + let parenthesized = match value.kind() { + ty::ConstKind::Expr(ty::Expr { + kind: ty::ExprKind::Cast { .. }, .. + }) => false, ty::ConstKind::Expr(_) => true, _ => false, }; self.maybe_parenthesized( |this| { this.typed_value( - |this| this.pretty_print_const(ct, print_ty), - |this| this.pretty_print_type(ty), + |this| this.pretty_print_const(value, print_ty), + |this| this.pretty_print_type(to_ty), " as ", ) }, parenthesized, )?; } else { - self.pretty_print_const(ct, print_ty)? + self.pretty_print_const(value, print_ty)? } } } diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index b417985889094..a621d255a03ec 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -6,8 +6,8 @@ use crate::ty::error::{ExpectedFound, TypeError}; use crate::ty::{ - self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, Expr, GenericArg, - GenericArgKind, GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, + self, ExistentialPredicate, ExistentialPredicateStableCmpExt as _, GenericArg, GenericArgKind, + GenericArgsRef, ImplSubject, Term, TermKind, Ty, TyCtxt, TypeFoldable, }; use rustc_hir as hir; use rustc_hir::def_id::DefId; @@ -665,46 +665,18 @@ pub fn structurally_relate_consts<'tcx, R: TypeRelation<'tcx>>( a.ty(), )); } - // Before calling relate on exprs, it is necessary to ensure that the nested consts - // have identical types. (ty::ConstKind::Expr(ae), ty::ConstKind::Expr(be)) => { - let r = relation; - - // FIXME(generic_const_exprs): is it possible to relate two consts which are not identical - // exprs? Should we care about that? - // FIXME(generic_const_exprs): relating the `ty()`s is a little weird since it is supposed to - // ICE If they mismatch. Unfortunately `ConstKind::Expr` is a little special and can be thought - // of as being generic over the argument types, however this is implicit so these types don't get - // related when we relate the args of the item this const arg is for. - let expr = match (ae, be) { - (Expr::Binop(a_op, al, ar), Expr::Binop(b_op, bl, br)) if a_op == b_op => { - r.relate(al.ty(), bl.ty())?; - r.relate(ar.ty(), br.ty())?; - Expr::Binop(a_op, r.consts(al, bl)?, r.consts(ar, br)?) - } - (Expr::UnOp(a_op, av), Expr::UnOp(b_op, bv)) if a_op == b_op => { - r.relate(av.ty(), bv.ty())?; - Expr::UnOp(a_op, r.consts(av, bv)?) - } - (Expr::Cast(ak, av, at), Expr::Cast(bk, bv, bt)) if ak == bk => { - r.relate(av.ty(), bv.ty())?; - Expr::Cast(ak, r.consts(av, bv)?, r.tys(at, bt)?) - } - (Expr::FunctionCall(af, aa), Expr::FunctionCall(bf, ba)) - if aa.len() == ba.len() => - { - r.relate(af.ty(), bf.ty())?; - let func = r.consts(af, bf)?; - let mut related_args = Vec::with_capacity(aa.len()); - for (a_arg, b_arg) in aa.iter().zip(ba.iter()) { - related_args.push(r.consts(a_arg, b_arg)?); - } - let related_args = tcx.mk_const_list(&related_args); - Expr::FunctionCall(func, related_args) - } + match (ae.kind, be.kind) { + (ty::ExprKind::Binop(a_binop), ty::ExprKind::Binop(b_binop)) + if a_binop == b_binop => {} + (ty::ExprKind::UnOp(a_unop), ty::ExprKind::UnOp(b_unop)) if a_unop == b_unop => {} + (ty::ExprKind::FunctionCall, ty::ExprKind::FunctionCall) => {} + (ty::ExprKind::Cast(a_kind), ty::ExprKind::Cast(b_kind)) if a_kind == b_kind => {} _ => return Err(TypeError::ConstMismatch(expected_found(a, b))), - }; - return Ok(ty::Const::new_expr(tcx, expr, a.ty())); + } + + let args = relation.relate(ae.args(), be.args())?; + return Ok(ty::Const::new_expr(tcx, ty::Expr::new(ae.kind, args), a.ty())); } _ => false, }; diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 90791bdd20dcd..7a291b4dbff63 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -147,14 +147,27 @@ impl<'tcx> DebugWithInfcx> for ty::consts::Expr<'tcx> { this: WithInfcx<'_, Infcx, &Self>, f: &mut core::fmt::Formatter<'_>, ) -> core::fmt::Result { - match this.data { - ty::Expr::Binop(op, lhs, rhs) => { - write!(f, "({op:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs)) + match this.data.kind { + ty::ExprKind::Binop(op) => { + let (lhs_ty, rhs_ty, lhs, rhs) = this.data.binop_args(); + write!( + f, + "({op:?}: ({:?}: {:?}), ({:?}: {:?}))", + &this.wrap(lhs), + &this.wrap(lhs_ty), + &this.wrap(rhs), + &this.wrap(rhs_ty), + ) } - ty::Expr::UnOp(op, rhs) => write!(f, "({op:?}: {:?})", &this.wrap(rhs)), - ty::Expr::FunctionCall(func, args) => { - write!(f, "{:?}(", &this.wrap(func))?; - for arg in args.as_slice().iter().rev().skip(1).rev() { + ty::ExprKind::UnOp(op) => { + let (rhs_ty, rhs) = this.data.unop_args(); + write!(f, "({op:?}: ({:?}: {:?}))", &this.wrap(rhs), &this.wrap(rhs_ty)) + } + ty::ExprKind::FunctionCall => { + let (func_ty, func, args) = this.data.call_args(); + let args = args.collect::>(); + write!(f, "({:?}: {:?})(", &this.wrap(func), &this.wrap(func_ty))?; + for arg in args.iter().rev().skip(1).rev() { write!(f, "{:?}, ", &this.wrap(arg))?; } if let Some(arg) = args.last() { @@ -163,8 +176,15 @@ impl<'tcx> DebugWithInfcx> for ty::consts::Expr<'tcx> { write!(f, ")") } - ty::Expr::Cast(cast_kind, lhs, rhs) => { - write!(f, "({cast_kind:?}: {:?}, {:?})", &this.wrap(lhs), &this.wrap(rhs)) + ty::ExprKind::Cast(kind) => { + let (value_ty, value, to_ty) = this.data.cast_args(); + write!( + f, + "({kind:?}: ({:?}: {:?}), {:?})", + &this.wrap(value), + &this.wrap(value_ty), + &this.wrap(to_ty) + ) } } } diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index a9421aacff839..58f69d772ecb7 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -222,24 +222,7 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::ConstKind::Value(_) | ty::ConstKind::Error(_) => {} - ty::ConstKind::Expr(expr) => match expr { - ty::Expr::UnOp(_, v) => push_inner(stack, v.into()), - ty::Expr::Binop(_, l, r) => { - push_inner(stack, r.into()); - push_inner(stack, l.into()) - } - ty::Expr::FunctionCall(func, args) => { - for a in args.iter().rev() { - push_inner(stack, a.into()); - } - push_inner(stack, func.into()); - } - ty::Expr::Cast(_, c, t) => { - push_inner(stack, t.into()); - push_inner(stack, c.into()); - } - }, - + ty::ConstKind::Expr(expr) => stack.extend(expr.args().iter().rev()), ty::ConstKind::Unevaluated(ct) => { stack.extend(ct.args.iter().rev()); } diff --git a/compiler/rustc_ty_utils/src/consts.rs b/compiler/rustc_ty_utils/src/consts.rs index e9112d232cbd6..8a42298f21646 100644 --- a/compiler/rustc_ty_utils/src/consts.rs +++ b/compiler/rustc_ty_utils/src/consts.rs @@ -148,17 +148,24 @@ fn recurse_build<'tcx>( for &id in args.iter() { new_args.push(recurse_build(tcx, body, id, root_span)?); } - let new_args = tcx.mk_const_list(&new_args); - ty::Const::new_expr(tcx, Expr::FunctionCall(fun, new_args), node.ty) + ty::Const::new_expr( + tcx, + Expr::new_call(tcx, fun.ty(), fun, new_args.into_iter()), + node.ty, + ) } &ExprKind::Binary { op, lhs, rhs } if check_binop(op) => { let lhs = recurse_build(tcx, body, lhs, root_span)?; let rhs = recurse_build(tcx, body, rhs, root_span)?; - ty::Const::new_expr(tcx, Expr::Binop(op, lhs, rhs), node.ty) + ty::Const::new_expr( + tcx, + Expr::new_binop(tcx, op, lhs.ty(), rhs.ty(), lhs, rhs), + node.ty, + ) } &ExprKind::Unary { op, arg } if check_unop(op) => { let arg = recurse_build(tcx, body, arg, root_span)?; - ty::Const::new_expr(tcx, Expr::UnOp(op, arg), node.ty) + ty::Const::new_expr(tcx, Expr::new_unop(tcx, op, arg.ty(), arg), node.ty) } // This is necessary so that the following compiles: // @@ -178,12 +185,22 @@ fn recurse_build<'tcx>( // "coercion cast" i.e. using a coercion or is a no-op. // This is important so that `N as usize as usize` doesn't unify with `N as usize`. (untested) &ExprKind::Use { source } => { - let arg = recurse_build(tcx, body, source, root_span)?; - ty::Const::new_expr(tcx, Expr::Cast(CastKind::Use, arg, node.ty), node.ty) + let value_ty = body.exprs[source].ty; + let value = recurse_build(tcx, body, source, root_span)?; + ty::Const::new_expr( + tcx, + Expr::new_cast(tcx, CastKind::Use, value_ty, value, node.ty), + node.ty, + ) } &ExprKind::Cast { source } => { - let arg = recurse_build(tcx, body, source, root_span)?; - ty::Const::new_expr(tcx, Expr::Cast(CastKind::As, arg, node.ty), node.ty) + let value_ty = body.exprs[source].ty; + let value = recurse_build(tcx, body, source, root_span)?; + ty::Const::new_expr( + tcx, + Expr::new_cast(tcx, CastKind::As, value_ty, value, node.ty), + node.ty, + ) } ExprKind::Borrow { arg, .. } => { let arg_node = &body.exprs[*arg]; From 7e08f80b34608e4aac2fcce1d9e85735b02034fe Mon Sep 17 00:00:00 2001 From: Boxy Date: Tue, 4 Jun 2024 00:39:35 +0100 Subject: [PATCH 11/12] Split smir `Const` into `TyConst` and `MirConst` --- .../rustc_smir/src/rustc_internal/internal.rs | 44 ++++----- compiler/rustc_smir/src/rustc_internal/mod.rs | 3 +- compiler/rustc_smir/src/rustc_smir/context.rs | 59 +++++++++--- .../rustc_smir/src/rustc_smir/convert/mir.rs | 20 ++-- .../rustc_smir/src/rustc_smir/convert/mod.rs | 2 + .../rustc_smir/src/rustc_smir/convert/ty.rs | 74 +++++++++++---- compiler/rustc_smir/src/rustc_smir/mod.rs | 13 ++- compiler/stable_mir/src/compiler_interface.rs | 22 +++-- compiler/stable_mir/src/mir/body.rs | 10 +- compiler/stable_mir/src/mir/pretty.rs | 16 ++-- compiler/stable_mir/src/mir/visit.rs | 25 +++-- compiler/stable_mir/src/ty.rs | 95 +++++++++++++------ compiler/stable_mir/src/visitor.rs | 30 +++++- .../ui-fulldeps/stable-mir/check_transform.rs | 6 +- 14 files changed, 285 insertions(+), 134 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs index 6ec710f97d16a..edfd48ed43b1a 100644 --- a/compiler/rustc_smir/src/rustc_internal/internal.rs +++ b/compiler/rustc_smir/src/rustc_internal/internal.rs @@ -5,17 +5,17 @@ // Prefer importing stable_mir over internal rustc constructs to make this file more readable. use crate::rustc_smir::Tables; -use rustc_middle::ty::{self as rustc_ty, Ty as InternalTy, TyCtxt}; +use rustc_middle::ty::{self as rustc_ty, Const as InternalConst, Ty as InternalTy, TyCtxt}; use rustc_span::Symbol; use stable_mir::abi::Layout; use stable_mir::mir::alloc::AllocId; use stable_mir::mir::mono::{Instance, MonoItem, StaticDef}; use stable_mir::mir::{BinOp, Mutability, Place, ProjectionElem, Safety, UnOp}; use stable_mir::ty::{ - Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, Const, - DynKind, ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, - GenericArgKind, GenericArgs, IndexedVal, IntTy, Movability, Pattern, Region, RigidTy, Span, - TermKind, TraitRef, Ty, UintTy, VariantDef, VariantIdx, + Abi, AdtDef, Binder, BoundRegionKind, BoundTyKind, BoundVariableKind, ClosureKind, DynKind, + ExistentialPredicate, ExistentialProjection, ExistentialTraitRef, FloatTy, FnSig, + GenericArgKind, GenericArgs, IndexedVal, IntTy, MirConst, Movability, Pattern, Region, RigidTy, + Span, TermKind, TraitRef, Ty, TyConst, UintTy, VariantDef, VariantIdx, }; use stable_mir::{CrateItem, CrateNum, DefId}; @@ -55,7 +55,7 @@ impl RustcInternal for GenericArgKind { let arg: rustc_ty::GenericArg<'tcx> = match self { GenericArgKind::Lifetime(reg) => reg.internal(tables, tcx).into(), GenericArgKind::Type(ty) => ty.internal(tables, tcx).into(), - GenericArgKind::Const(cnst) => ty_const(cnst, tables, tcx).into(), + GenericArgKind::Const(cnst) => cnst.internal(tables, tcx).into(), }; tcx.lift(arg).unwrap() } @@ -76,13 +76,20 @@ impl RustcInternal for Ty { } } +impl RustcInternal for TyConst { + type T<'tcx> = InternalConst<'tcx>; + fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { + tcx.lift(tables.ty_consts[self.id]).unwrap() + } +} + impl RustcInternal for Pattern { type T<'tcx> = rustc_ty::Pattern<'tcx>; fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { tcx.mk_pat(match self { Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range { - start: start.as_ref().map(|c| ty_const(c, tables, tcx)), - end: end.as_ref().map(|c| ty_const(c, tables, tcx)), + start: start.as_ref().map(|c| c.internal(tables, tcx)), + end: end.as_ref().map(|c| c.internal(tables, tcx)), include_end: *include_end, }, }) @@ -101,7 +108,7 @@ impl RustcInternal for RigidTy { RigidTy::Float(float_ty) => rustc_ty::TyKind::Float(float_ty.internal(tables, tcx)), RigidTy::Never => rustc_ty::TyKind::Never, RigidTy::Array(ty, cnst) => { - rustc_ty::TyKind::Array(ty.internal(tables, tcx), ty_const(cnst, tables, tcx)) + rustc_ty::TyKind::Array(ty.internal(tables, tcx), cnst.internal(tables, tcx)) } RigidTy::Pat(ty, pat) => { rustc_ty::TyKind::Pat(ty.internal(tables, tcx), pat.internal(tables, tcx)) @@ -239,23 +246,10 @@ impl RustcInternal for VariantDef { } } -fn ty_const<'tcx>( - constant: &Const, - tables: &mut Tables<'_>, - tcx: TyCtxt<'tcx>, -) -> rustc_ty::Const<'tcx> { - match constant.internal(tables, tcx) { - rustc_middle::mir::Const::Ty(c) => c, - cnst => { - panic!("Trying to convert constant `{constant:?}` to type constant, but found {cnst:?}") - } - } -} - -impl RustcInternal for Const { +impl RustcInternal for MirConst { type T<'tcx> = rustc_middle::mir::Const<'tcx>; fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { - let constant = tables.constants[self.id]; + let constant = tables.mir_consts[self.id]; match constant { rustc_middle::mir::Const::Ty(ty) => rustc_middle::mir::Const::Ty(tcx.lift(ty).unwrap()), rustc_middle::mir::Const::Unevaluated(uneval, ty) => { @@ -392,7 +386,7 @@ impl RustcInternal for TermKind { fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> { match self { TermKind::Type(ty) => ty.internal(tables, tcx).into(), - TermKind::Const(const_) => ty_const(const_, tables, tcx).into(), + TermKind::Const(cnst) => cnst.internal(tables, tcx).into(), } } } diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs index 6e870728bafc4..810ffc142a09f 100644 --- a/compiler/rustc_smir/src/rustc_internal/mod.rs +++ b/compiler/rustc_smir/src/rustc_internal/mod.rs @@ -214,7 +214,8 @@ where spans: IndexMap::default(), types: IndexMap::default(), instances: IndexMap::default(), - constants: IndexMap::default(), + ty_consts: IndexMap::default(), + mir_consts: IndexMap::default(), layouts: IndexMap::default(), })); stable_mir::compiler_interface::run(&tables, || init(&tables, f)) diff --git a/compiler/rustc_smir/src/rustc_smir/context.rs b/compiler/rustc_smir/src/rustc_smir/context.rs index fa7b2a30ba6cf..9822ed79e2bd9 100644 --- a/compiler/rustc_smir/src/rustc_smir/context.rs +++ b/compiler/rustc_smir/src/rustc_smir/context.rs @@ -6,7 +6,6 @@ #![allow(rustc::usage_of_qualified_ty)] use rustc_abi::HasDataLayout; -use rustc_middle::ty; use rustc_middle::ty::layout::{ FnAbiOf, FnAbiOfHelpers, HasParamEnv, HasTyCtxt, LayoutOf, LayoutOfHelpers, }; @@ -14,6 +13,7 @@ use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths}; use rustc_middle::ty::{ GenericPredicates, Instance, List, ParamEnv, ScalarInt, TyCtxt, TypeVisitableExt, ValTree, }; +use rustc_middle::{mir, ty}; use rustc_span::def_id::LOCAL_CRATE; use stable_mir::abi::{FnAbi, Layout, LayoutShape}; use stable_mir::compiler_interface::Context; @@ -22,9 +22,9 @@ use stable_mir::mir::mono::{InstanceDef, StaticDef}; use stable_mir::mir::{BinOp, Body, Place, UnOp}; use stable_mir::target::{MachineInfo, MachineSize}; use stable_mir::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef, - ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, Ty, TyKind, - UintTy, VariantDef, + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef, + ForeignItemKind, GenericArgs, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, Ty, + TyConst, TyKind, UintTy, VariantDef, }; use stable_mir::{Crate, CrateDef, CrateItem, CrateNum, DefId, Error, Filename, ItemKind, Symbol}; use std::cell::RefCell; @@ -360,7 +360,15 @@ impl<'tcx> Context for TablesWrapper<'tcx> { def.internal(&mut *tables, tcx).fields.iter().map(|f| f.stable(&mut *tables)).collect() } - fn eval_target_usize(&self, cnst: &Const) -> Result { + fn eval_target_usize(&self, cnst: &MirConst) -> Result { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + let mir_const = cnst.internal(&mut *tables, tcx); + mir_const + .try_eval_target_usize(tables.tcx, ParamEnv::empty()) + .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) + } + fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let mir_const = cnst.internal(&mut *tables, tcx); @@ -369,7 +377,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .ok_or_else(|| Error::new(format!("Const `{cnst:?}` cannot be encoded as u64"))) } - fn try_new_const_zst(&self, ty: Ty) -> Result { + fn try_new_const_zst(&self, ty: Ty) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty_internal = ty.internal(&mut *tables, tcx); @@ -390,25 +398,45 @@ impl<'tcx> Context for TablesWrapper<'tcx> { ))); } - Ok(ty::Const::zero_sized(tables.tcx, ty_internal).stable(&mut *tables)) + Ok(mir::Const::Ty(ty::Const::zero_sized(tables.tcx, ty_internal)).stable(&mut *tables)) } - fn new_const_str(&self, value: &str) -> Const { + fn new_const_str(&self, value: &str) -> MirConst { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_static_str(tcx); let bytes = value.as_bytes(); let val_tree = ty::ValTree::from_raw_bytes(tcx, bytes); - ty::Const::new_value(tcx, val_tree, ty).stable(&mut *tables) + let ct = ty::Const::new_value(tcx, val_tree, ty); + super::convert::mir_const_from_ty_const(&mut *tables, ct, ty) } - fn new_const_bool(&self, value: bool) -> Const { + fn new_const_bool(&self, value: bool) -> MirConst { let mut tables = self.0.borrow_mut(); - ty::Const::from_bool(tables.tcx, value).stable(&mut *tables) + let ct = ty::Const::from_bool(tables.tcx, value); + let ty = tables.tcx.types.bool; + super::convert::mir_const_from_ty_const(&mut *tables, ct, ty) } - fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { + fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result { + let mut tables = self.0.borrow_mut(); + let tcx = tables.tcx; + let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); + let size = tables.tcx.layout_of(ParamEnv::empty().and(ty)).unwrap().size; + + // We don't use Const::from_bits since it doesn't have any error checking. + let scalar = ScalarInt::try_from_uint(value, size).ok_or_else(|| { + Error::new(format!("Value overflow: cannot convert `{value}` to `{ty}`.")) + })?; + let ct = ty::Const::new_value(tables.tcx, ValTree::from_scalar_int(scalar), ty); + Ok(super::convert::mir_const_from_ty_const(&mut *tables, ct, ty)) + } + fn try_new_ty_const_uint( + &self, + value: u128, + uint_ty: UintTy, + ) -> Result { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; let ty = ty::Ty::new_uint(tcx, uint_ty.internal(&mut *tables, tcx)); @@ -453,7 +481,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> { .stable(&mut *tables) } - fn const_pretty(&self, cnst: &stable_mir::ty::Const) -> String { + fn mir_const_pretty(&self, cnst: &stable_mir::ty::MirConst) -> String { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; cnst.internal(&mut *tables, tcx).to_string() @@ -474,6 +502,11 @@ impl<'tcx> Context for TablesWrapper<'tcx> { tables.types[ty].kind().stable(&mut *tables) } + fn ty_const_pretty(&self, ct: stable_mir::ty::TyConstId) -> String { + let tables = self.0.borrow_mut(); + tables.ty_consts[ct].to_string() + } + fn rigid_ty_discriminant_ty(&self, ty: &RigidTy) -> stable_mir::ty::Ty { let mut tables = self.0.borrow_mut(); let tcx = tables.tcx; diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs index a1a5c09ef0af4..1c87293209c68 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs @@ -6,7 +6,7 @@ use rustc_middle::mir::interpret::alloc_range; use rustc_middle::mir::mono::MonoItem; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::{ConstOperand, Statement, UserTypeProjection, VarDebugInfoFragment}; -use stable_mir::ty::{Allocation, Const, ConstantKind}; +use stable_mir::ty::{Allocation, ConstantKind, MirConst}; use stable_mir::{opaque, Error}; use crate::rustc_smir::{alloc, Stable, Tables}; @@ -724,11 +724,16 @@ impl<'tcx> Stable<'tcx> for mir::interpret::GlobalAlloc<'tcx> { } impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { - type T = stable_mir::ty::Const; + type T = stable_mir::ty::MirConst; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { + let id = tables.intern_mir_const(tables.tcx.lift(*self).unwrap()); match *self { - mir::Const::Ty(c) => c.stable(tables), + mir::Const::Ty(c) => MirConst::new( + stable_mir::ty::ConstantKind::Ty(c.stable(tables)), + c.ty().stable(tables), + id, + ), mir::Const::Unevaluated(unev_const, ty) => { let kind = stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { @@ -737,21 +742,18 @@ impl<'tcx> Stable<'tcx> for rustc_middle::mir::Const<'tcx> { promoted: unev_const.promoted.map(|u| u.as_u32()), }); let ty = ty.stable(tables); - let id = tables.intern_const(tables.tcx.lift(*self).unwrap()); - Const::new(kind, ty, id) + MirConst::new(kind, ty, id) } mir::Const::Val(mir::ConstValue::ZeroSized, ty) => { let ty = ty.stable(tables); - let id = tables.intern_const(tables.tcx.lift(*self).unwrap()); - Const::new(ConstantKind::ZeroSized, ty, id) + MirConst::new(ConstantKind::ZeroSized, ty, id) } mir::Const::Val(val, ty) => { let ty = tables.tcx.lift(ty).unwrap(); let val = tables.tcx.lift(val).unwrap(); let kind = ConstantKind::Allocated(alloc::new_allocation(ty, val, tables)); let ty = ty.stable(tables); - let id = tables.intern_const(tables.tcx.lift(*self).unwrap()); - Const::new(kind, ty, id) + MirConst::new(kind, ty, id) } } } diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs index 736378a530f0a..50687935473a7 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/mod.rs @@ -9,6 +9,8 @@ mod error; mod mir; mod ty; +pub use ty::mir_const_from_ty_const; + impl<'tcx> Stable<'tcx> for rustc_hir::Safety { type T = stable_mir::mir::Safety; fn stable(&self, _: &mut Tables<'_>) -> Self::T { diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs index 66708def00f19..1f3356f579fe6 100644 --- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs +++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs @@ -3,8 +3,7 @@ use rustc_middle::ty::Ty; use rustc_middle::{mir, ty}; use stable_mir::ty::{ - AdtKind, Const, ConstantKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, - TyKind, UintTy, + AdtKind, FloatTy, GenericArgs, GenericParamDef, IntTy, Region, RigidTy, TyKind, UintTy, }; use crate::rustc_smir::{alloc, Stable, Tables}; @@ -410,8 +409,50 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> { } } +pub fn mir_const_from_ty_const<'tcx>( + tables: &mut Tables<'tcx>, + ty_const: ty::Const<'tcx>, + ty: Ty<'tcx>, +) -> stable_mir::ty::MirConst { + let kind = match ty_const.kind() { + ty::Value(val) => { + let val = match val { + ty::ValTree::Leaf(scalar) => ty::ValTree::Leaf(scalar), + ty::ValTree::Branch(branch) => { + ty::ValTree::Branch(tables.tcx.lift(branch).unwrap()) + } + }; + let ty = tables.tcx.lift(ty).unwrap(); + let const_val = tables.tcx.valtree_to_const_val((ty, val)); + if matches!(const_val, mir::ConstValue::ZeroSized) { + stable_mir::ty::ConstantKind::ZeroSized + } else { + stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( + ty, const_val, tables, + )) + } + } + ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)), + ty::ErrorCt(_) => unreachable!(), + ty::InferCt(_) => unreachable!(), + ty::BoundCt(_, _) => unimplemented!(), + ty::PlaceholderCt(_) => unimplemented!(), + ty::Unevaluated(uv) => { + stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { + def: tables.const_def(uv.def), + args: uv.args.stable(tables), + promoted: None, + }) + } + ty::ExprCt(_) => unimplemented!(), + }; + let stable_ty = tables.intern_ty(ty); + let id = tables.intern_mir_const(mir::Const::Ty(ty_const)); + stable_mir::ty::MirConst::new(kind, stable_ty, id) +} + impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { - type T = stable_mir::ty::Const; + type T = stable_mir::ty::TyConst; fn stable(&self, tables: &mut Tables<'_>) -> Self::T { let kind = match self.kind() { @@ -425,30 +466,27 @@ impl<'tcx> Stable<'tcx> for ty::Const<'tcx> { let ty = tables.tcx.lift(self.ty()).unwrap(); let const_val = tables.tcx.valtree_to_const_val((ty, val)); if matches!(const_val, mir::ConstValue::ZeroSized) { - ConstantKind::ZeroSized + stable_mir::ty::TyConstKind::ZSTValue(ty.stable(tables)) } else { - stable_mir::ty::ConstantKind::Allocated(alloc::new_allocation( - ty, const_val, tables, - )) + stable_mir::ty::TyConstKind::Value( + ty.stable(tables), + alloc::new_allocation(ty, const_val, tables), + ) } } - ty::ParamCt(param) => stable_mir::ty::ConstantKind::Param(param.stable(tables)), + ty::ParamCt(param) => stable_mir::ty::TyConstKind::Param(param.stable(tables)), + ty::Unevaluated(uv) => stable_mir::ty::TyConstKind::Unevaluated( + tables.const_def(uv.def), + uv.args.stable(tables), + ), ty::ErrorCt(_) => unreachable!(), ty::InferCt(_) => unreachable!(), ty::BoundCt(_, _) => unimplemented!(), ty::PlaceholderCt(_) => unimplemented!(), - ty::Unevaluated(uv) => { - stable_mir::ty::ConstantKind::Unevaluated(stable_mir::ty::UnevaluatedConst { - def: tables.const_def(uv.def), - args: uv.args.stable(tables), - promoted: None, - }) - } ty::ExprCt(_) => unimplemented!(), }; - let ty = self.ty().stable(tables); - let id = tables.intern_const(mir::Const::Ty(tables.tcx.lift(*self).unwrap())); - Const::new(kind, ty, id) + let id = tables.intern_ty_const(tables.tcx.lift(*self).unwrap()); + stable_mir::ty::TyConst::new(kind, id) } } diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index aba7e7dc9c21d..d13e780332632 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -14,7 +14,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use stable_mir::abi::Layout; use stable_mir::mir::mono::InstanceDef; -use stable_mir::ty::{ConstId, Span}; +use stable_mir::ty::{MirConstId, Span, TyConstId}; use stable_mir::{CtorKind, ItemKind}; use std::ops::RangeInclusive; use tracing::debug; @@ -33,7 +33,8 @@ pub struct Tables<'tcx> { pub(crate) spans: IndexMap, pub(crate) types: IndexMap, stable_mir::ty::Ty>, pub(crate) instances: IndexMap, InstanceDef>, - pub(crate) constants: IndexMap, ConstId>, + pub(crate) ty_consts: IndexMap, TyConstId>, + pub(crate) mir_consts: IndexMap, MirConstId>, pub(crate) layouts: IndexMap, Layout>, } @@ -42,8 +43,12 @@ impl<'tcx> Tables<'tcx> { self.types.create_or_fetch(ty) } - pub(crate) fn intern_const(&mut self, constant: mir::Const<'tcx>) -> ConstId { - self.constants.create_or_fetch(constant) + pub(crate) fn intern_ty_const(&mut self, ct: ty::Const<'tcx>) -> TyConstId { + self.ty_consts.create_or_fetch(ct) + } + + pub(crate) fn intern_mir_const(&mut self, constant: mir::Const<'tcx>) -> MirConstId { + self.mir_consts.create_or_fetch(constant) } pub(crate) fn has_body(&self, instance: Instance<'tcx>) -> bool { diff --git a/compiler/stable_mir/src/compiler_interface.rs b/compiler/stable_mir/src/compiler_interface.rs index 858ce5301d84c..085dfd9ea8909 100644 --- a/compiler/stable_mir/src/compiler_interface.rs +++ b/compiler/stable_mir/src/compiler_interface.rs @@ -11,10 +11,10 @@ use crate::mir::mono::{Instance, InstanceDef, StaticDef}; use crate::mir::{BinOp, Body, Place, UnOp}; use crate::target::MachineInfo; use crate::ty::{ - AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, Const, FieldDef, FnDef, ForeignDef, + AdtDef, AdtKind, Allocation, ClosureDef, ClosureKind, FieldDef, FnDef, ForeignDef, ForeignItemKind, ForeignModule, ForeignModuleDef, GenericArgs, GenericPredicates, Generics, - ImplDef, ImplTrait, IntrinsicDef, LineInfo, PolyFnSig, RigidTy, Span, TraitDecl, TraitDef, Ty, - TyKind, UintTy, VariantDef, + ImplDef, ImplTrait, IntrinsicDef, LineInfo, MirConst, PolyFnSig, RigidTy, Span, TraitDecl, + TraitDef, Ty, TyConst, TyConstId, TyKind, UintTy, VariantDef, }; use crate::{ mir, Crate, CrateItem, CrateItems, CrateNum, DefId, Error, Filename, ImplTraitDecls, ItemKind, @@ -109,19 +109,21 @@ pub trait Context { fn variant_fields(&self, def: VariantDef) -> Vec; /// Evaluate constant as a target usize. - fn eval_target_usize(&self, cnst: &Const) -> Result; + fn eval_target_usize(&self, cnst: &MirConst) -> Result; + fn eval_target_usize_ty(&self, cnst: &TyConst) -> Result; /// Create a new zero-sized constant. - fn try_new_const_zst(&self, ty: Ty) -> Result; + fn try_new_const_zst(&self, ty: Ty) -> Result; /// Create a new constant that represents the given string value. - fn new_const_str(&self, value: &str) -> Const; + fn new_const_str(&self, value: &str) -> MirConst; /// Create a new constant that represents the given boolean value. - fn new_const_bool(&self, value: bool) -> Const; + fn new_const_bool(&self, value: bool) -> MirConst; /// Create a new constant that represents the given value. - fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; + fn try_new_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; + fn try_new_ty_const_uint(&self, value: u128, uint_ty: UintTy) -> Result; /// Create a new type from the given kind. fn new_rigid_ty(&self, kind: RigidTy) -> Ty; @@ -136,11 +138,13 @@ pub trait Context { fn def_ty_with_args(&self, item: DefId, args: &GenericArgs) -> Ty; /// Returns literal value of a const as a string. - fn const_pretty(&self, cnst: &Const) -> String; + fn mir_const_pretty(&self, cnst: &MirConst) -> String; /// `Span` of an item fn span_of_an_item(&self, def_id: DefId) -> Span; + fn ty_const_pretty(&self, ct: TyConstId) -> String; + /// Obtain the representation of a type. fn ty_pretty(&self, ty: Ty) -> String; diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs index 4c779ae96a81b..43e4682dc1008 100644 --- a/compiler/stable_mir/src/mir/body.rs +++ b/compiler/stable_mir/src/mir/body.rs @@ -1,8 +1,8 @@ use crate::compiler_interface::with; use crate::mir::pretty::function_body; use crate::ty::{ - AdtDef, ClosureDef, Const, CoroutineDef, GenericArgs, Movability, Region, RigidTy, Ty, TyKind, - VariantIdx, + AdtDef, ClosureDef, CoroutineDef, GenericArgs, MirConst, Movability, Region, RigidTy, Ty, + TyConst, TyKind, VariantIdx, }; use crate::{Error, Opaque, Span, Symbol}; use std::io; @@ -524,7 +524,7 @@ pub enum Rvalue { /// Corresponds to source code like `[x; 32]`. /// /// [#74836]: https://github.com/rust-lang/rust/issues/74836 - Repeat(Operand, Const), + Repeat(Operand, TyConst), /// Transmutes a `*mut u8` into shallow-initialized `Box`. /// @@ -718,7 +718,7 @@ pub enum VarDebugInfoContents { pub struct ConstOperand { pub span: Span, pub user_ty: Option, - pub const_: Const, + pub const_: MirConst, } // In MIR ProjectionElem is parameterized on the second Field argument and the Index argument. This @@ -833,7 +833,7 @@ type UserTypeAnnotationIndex = usize; pub struct Constant { pub span: Span, pub user_ty: Option, - pub literal: Const, + pub literal: MirConst, } /// The possible branch sites of a [TerminatorKind::SwitchInt]. diff --git a/compiler/stable_mir/src/mir/pretty.rs b/compiler/stable_mir/src/mir/pretty.rs index 580dc1a2b88fc..2fb180b84c7c3 100644 --- a/compiler/stable_mir/src/mir/pretty.rs +++ b/compiler/stable_mir/src/mir/pretty.rs @@ -1,5 +1,5 @@ use crate::mir::{Operand, Place, Rvalue, StatementKind, UnwindAction, VarDebugInfoContents}; -use crate::ty::{Const, IndexedVal, Ty}; +use crate::ty::{IndexedVal, MirConst, Ty, TyConst}; use crate::{with, Body, Mutability}; use fmt::{Display, Formatter}; use std::fmt::Debug; @@ -46,7 +46,7 @@ pub(crate) fn function_body(writer: &mut W, body: &Body, name: &str) - VarDebugInfoContents::Place(place) => { format!("{place:?}") } - VarDebugInfoContents::Const(constant) => pretty_const(&constant.const_), + VarDebugInfoContents::Const(constant) => pretty_mir_const(&constant.const_), }; writeln!(writer, " debug {} => {};", info.name, content) })?; @@ -310,12 +310,16 @@ fn pretty_operand(operand: &Operand) -> String { Operand::Move(mv) => { format!("move {:?}", mv) } - Operand::Constant(cnst) => pretty_const(&cnst.literal), + Operand::Constant(cnst) => pretty_mir_const(&cnst.literal), } } -fn pretty_const(literal: &Const) -> String { - with(|cx| cx.const_pretty(literal)) +fn pretty_mir_const(literal: &MirConst) -> String { + with(|cx| cx.mir_const_pretty(literal)) +} + +fn pretty_ty_const(ct: &TyConst) -> String { + with(|cx| cx.ty_const_pretty(ct.id)) } fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { @@ -359,7 +363,7 @@ fn pretty_rvalue(writer: &mut W, rval: &Rvalue) -> io::Result<()> { write!(writer, "{kind}{:?}", place) } Rvalue::Repeat(op, cnst) => { - write!(writer, "{} \" \" {}", &pretty_operand(op), cnst.ty()) + write!(writer, "{} \" \" {}", &pretty_operand(op), &pretty_ty_const(cnst)) } Rvalue::ShallowInitBox(_, _) => Ok(()), Rvalue::ThreadLocalRef(item) => { diff --git a/compiler/stable_mir/src/mir/visit.rs b/compiler/stable_mir/src/mir/visit.rs index 24296e9e8778b..10f30083dc2d9 100644 --- a/compiler/stable_mir/src/mir/visit.rs +++ b/compiler/stable_mir/src/mir/visit.rs @@ -36,7 +36,7 @@ //! variant argument) that does not require visiting. use crate::mir::*; -use crate::ty::{Const, GenericArgs, Region, Ty}; +use crate::ty::{GenericArgs, MirConst, Region, Ty, TyConst}; use crate::{Error, Opaque, Span}; pub trait MirVisitor { @@ -112,8 +112,13 @@ pub trait MirVisitor { self.super_constant(constant, location) } - fn visit_const(&mut self, constant: &Const, location: Location) { - self.super_const(constant, location) + fn visit_mir_const(&mut self, constant: &MirConst, location: Location) { + self.super_mir_const(constant, location) + } + + fn visit_ty_const(&mut self, constant: &TyConst, location: Location) { + let _ = location; + self.super_ty_const(constant) } fn visit_region(&mut self, region: &Region, location: Location) { @@ -339,7 +344,7 @@ pub trait MirVisitor { } Rvalue::Repeat(op, constant) => { self.visit_operand(op, location); - self.visit_const(constant, location); + self.visit_ty_const(constant, location); } Rvalue::ShallowInitBox(op, ty) => { self.visit_ty(ty, location); @@ -378,14 +383,18 @@ pub trait MirVisitor { fn super_constant(&mut self, constant: &Constant, location: Location) { let Constant { span, user_ty: _, literal } = constant; self.visit_span(span); - self.visit_const(literal, location); + self.visit_mir_const(literal, location); } - fn super_const(&mut self, constant: &Const, location: Location) { - let Const { kind: _, ty, id: _ } = constant; + fn super_mir_const(&mut self, constant: &MirConst, location: Location) { + let MirConst { kind: _, ty, id: _ } = constant; self.visit_ty(ty, location); } + fn super_ty_const(&mut self, constant: &TyConst) { + let _ = constant; + } + fn super_region(&mut self, region: &Region) { let _ = region; } @@ -407,7 +416,7 @@ pub trait MirVisitor { self.visit_place(place, PlaceContext::NON_USE, location); } VarDebugInfoContents::Const(constant) => { - self.visit_const(&constant.const_, location); + self.visit_mir_const(&constant.const_, location); } } } diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs index 50bf0a5d74ef3..bcbe87f7303b3 100644 --- a/compiler/stable_mir/src/ty.rs +++ b/compiler/stable_mir/src/ty.rs @@ -28,11 +28,11 @@ impl Ty { /// Create a new array type. pub fn try_new_array(elem_ty: Ty, size: u64) -> Result { - Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, Const::try_from_target_usize(size)?))) + Ok(Ty::from_rigid_kind(RigidTy::Array(elem_ty, TyConst::try_from_target_usize(size)?))) } /// Create a new array type from Const length. - pub fn new_array_with_const_len(elem_ty: Ty, len: Const) -> Ty { + pub fn new_array_with_const_len(elem_ty: Ty, len: TyConst) -> Ty { Ty::from_rigid_kind(RigidTy::Array(elem_ty, len)) } @@ -101,24 +101,66 @@ impl Ty { /// Represents a pattern in the type system #[derive(Clone, Debug, Eq, PartialEq)] pub enum Pattern { - Range { start: Option, end: Option, include_end: bool }, + Range { start: Option, end: Option, include_end: bool }, } -/// Represents a constant in MIR or from the Type system. +/// Represents a constant in the type system #[derive(Clone, Debug, Eq, PartialEq)] -pub struct Const { +pub struct TyConst { + pub(crate) kind: TyConstKind, + pub id: TyConstId, +} + +impl TyConst { + pub fn new(kind: TyConstKind, id: TyConstId) -> TyConst { + Self { kind, id } + } + + /// Retrieve the constant kind. + pub fn kind(&self) -> &TyConstKind { + &self.kind + } + + /// Creates an interned usize constant. + fn try_from_target_usize(val: u64) -> Result { + with(|cx| cx.try_new_ty_const_uint(val.into(), UintTy::Usize)) + } + + /// Try to evaluate to a target `usize`. + pub fn eval_target_usize(&self) -> Result { + with(|cx| cx.eval_target_usize_ty(self)) + } +} + +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum TyConstKind { + Param(ParamConst), + Bound(DebruijnIndex, BoundVar), + Unevaluated(ConstDef, GenericArgs), + + // FIXME: These should be a valtree + Value(Ty, Allocation), + ZSTValue(Ty), +} + +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct TyConstId(usize); + +/// Represents a constant in MIR +#[derive(Clone, Debug, Eq, PartialEq)] +pub struct MirConst { /// The constant kind. pub(crate) kind: ConstantKind, /// The constant type. pub(crate) ty: Ty, /// Used for internal tracking of the internal constant. - pub id: ConstId, + pub id: MirConstId, } -impl Const { +impl MirConst { /// Build a constant. Note that this should only be used by the compiler. - pub fn new(kind: ConstantKind, ty: Ty, id: ConstId) -> Const { - Const { kind, ty, id } + pub fn new(kind: ConstantKind, ty: Ty, id: MirConstId) -> MirConst { + MirConst { kind, ty, id } } /// Retrieve the constant kind. @@ -131,11 +173,6 @@ impl Const { self.ty } - /// Creates an interned usize constant. - fn try_from_target_usize(val: u64) -> Result { - with(|cx| cx.try_new_const_uint(val.into(), UintTy::Usize)) - } - /// Try to evaluate to a target `usize`. pub fn eval_target_usize(&self) -> Result { with(|cx| cx.eval_target_usize(self)) @@ -143,7 +180,7 @@ impl Const { /// Create a constant that represents a new zero-sized constant of type T. /// Fails if the type is not a ZST or if it doesn't have a known size. - pub fn try_new_zero_sized(ty: Ty) -> Result { + pub fn try_new_zero_sized(ty: Ty) -> Result { with(|cx| cx.try_new_const_zst(ty)) } @@ -152,23 +189,23 @@ impl Const { /// Note that there is no guarantee today about duplication of the same constant. /// I.e.: Calling this function multiple times with the same argument may or may not return /// the same allocation. - pub fn from_str(value: &str) -> Const { + pub fn from_str(value: &str) -> MirConst { with(|cx| cx.new_const_str(value)) } /// Build a new constant that represents the given boolean value. - pub fn from_bool(value: bool) -> Const { + pub fn from_bool(value: bool) -> MirConst { with(|cx| cx.new_const_bool(value)) } /// Build a new constant that represents the given unsigned integer. - pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result { + pub fn try_from_uint(value: u128, uint_ty: UintTy) -> Result { with(|cx| cx.try_new_const_uint(value, uint_ty)) } } #[derive(Clone, Copy, Debug, PartialEq, Eq)] -pub struct ConstId(usize); +pub struct MirConstId(usize); type Ident = Opaque; @@ -484,7 +521,7 @@ pub enum RigidTy { Adt(AdtDef, GenericArgs), Foreign(ForeignDef), Str, - Array(Ty, Const), + Array(Ty, TyConst), Pat(Ty, Pattern), Slice(Ty), RawPtr(Ty, Mutability), @@ -866,7 +903,7 @@ impl std::ops::Index for GenericArgs { } impl std::ops::Index for GenericArgs { - type Output = Const; + type Output = TyConst; fn index(&self, index: ParamConst) -> &Self::Output { self.0[index.index as usize].expect_const() @@ -877,7 +914,7 @@ impl std::ops::Index for GenericArgs { pub enum GenericArgKind { Lifetime(Region), Type(Ty), - Const(Const), + Const(TyConst), } impl GenericArgKind { @@ -894,7 +931,7 @@ impl GenericArgKind { /// Panic if this generic argument is not a const, otherwise /// return the const. #[track_caller] - pub fn expect_const(&self) -> &Const { + pub fn expect_const(&self) -> &TyConst { match self { GenericArgKind::Const(c) => c, _ => panic!("{self:?}"), @@ -913,7 +950,7 @@ impl GenericArgKind { #[derive(Clone, Debug, Eq, PartialEq)] pub enum TermKind { Type(Ty), - Const(Const), + Const(TyConst), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -1202,6 +1239,7 @@ impl Allocation { #[derive(Clone, Debug, Eq, PartialEq)] pub enum ConstantKind { + Ty(TyConst), Allocated(Allocation), Unevaluated(UnevaluatedConst), Param(ParamConst), @@ -1335,7 +1373,7 @@ pub enum PredicateKind { ObjectSafe(TraitDef), SubType(SubtypePredicate), Coerce(CoercePredicate), - ConstEquate(Const, Const), + ConstEquate(TyConst, TyConst), Ambiguous, AliasRelate(TermKind, TermKind, AliasRelationDirection), } @@ -1346,9 +1384,9 @@ pub enum ClauseKind { RegionOutlives(RegionOutlivesPredicate), TypeOutlives(TypeOutlivesPredicate), Projection(ProjectionPredicate), - ConstArgHasType(Const, Ty), + ConstArgHasType(TyConst, Ty), WellFormed(GenericArgKind), - ConstEvaluatable(Const), + ConstEvaluatable(TyConst), } #[derive(Clone, Debug, Eq, PartialEq)] @@ -1426,7 +1464,8 @@ macro_rules! index_impl { }; } -index_impl!(ConstId); +index_impl!(TyConstId); +index_impl!(MirConstId); index_impl!(Ty); index_impl!(Span); diff --git a/compiler/stable_mir/src/visitor.rs b/compiler/stable_mir/src/visitor.rs index 2d7159f87fec3..fc1da8fafe486 100644 --- a/compiler/stable_mir/src/visitor.rs +++ b/compiler/stable_mir/src/visitor.rs @@ -1,10 +1,10 @@ use std::ops::ControlFlow; -use crate::Opaque; +use crate::{ty::TyConst, Opaque}; use super::ty::{ - Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, - Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst, + Allocation, Binder, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs, + MirConst, Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst, }; pub trait Visitor: Sized { @@ -12,7 +12,7 @@ pub trait Visitor: Sized { fn visit_ty(&mut self, ty: &Ty) -> ControlFlow { ty.super_visit(self) } - fn visit_const(&mut self, c: &Const) -> ControlFlow { + fn visit_const(&mut self, c: &TyConst) -> ControlFlow { c.super_visit(self) } fn visit_reg(&mut self, reg: &Region) -> ControlFlow { @@ -42,12 +42,32 @@ impl Visitable for Ty { } } -impl Visitable for Const { +impl Visitable for TyConst { fn visit(&self, visitor: &mut V) -> ControlFlow { visitor.visit_const(self) } + fn super_visit(&self, visitor: &mut V) -> ControlFlow { + match &self.kind { + crate::ty::TyConstKind::Param(_) => {} + crate::ty::TyConstKind::Bound(_, _) => {} + crate::ty::TyConstKind::Unevaluated(_, args) => args.visit(visitor)?, + crate::ty::TyConstKind::Value(ty, alloc) => { + alloc.visit(visitor)?; + ty.visit(visitor)?; + } + crate::ty::TyConstKind::ZSTValue(ty) => ty.visit(visitor)?, + } + ControlFlow::Continue(()) + } +} + +impl Visitable for MirConst { + fn visit(&self, visitor: &mut V) -> ControlFlow { + self.super_visit(visitor) + } fn super_visit(&self, visitor: &mut V) -> ControlFlow { match &self.kind() { + super::ty::ConstantKind::Ty(ct) => ct.visit(visitor)?, super::ty::ConstantKind::Allocated(alloc) => alloc.visit(visitor)?, super::ty::ConstantKind::Unevaluated(uv) => uv.visit(visitor)?, super::ty::ConstantKind::Param(_) | super::ty::ConstantKind::ZeroSized => {} diff --git a/tests/ui-fulldeps/stable-mir/check_transform.rs b/tests/ui-fulldeps/stable-mir/check_transform.rs index 6345ee24f7893..b203e76e54f45 100644 --- a/tests/ui-fulldeps/stable-mir/check_transform.rs +++ b/tests/ui-fulldeps/stable-mir/check_transform.rs @@ -22,7 +22,7 @@ use rustc_smir::rustc_internal; use stable_mir::mir::alloc::GlobalAlloc; use stable_mir::mir::mono::Instance; use stable_mir::mir::{Body, Constant, Operand, Rvalue, StatementKind, TerminatorKind}; -use stable_mir::ty::{Const, ConstantKind}; +use stable_mir::ty::{ConstantKind, MirConst}; use stable_mir::{CrateDef, CrateItems, ItemKind}; use std::convert::TryFrom; use std::io::Write; @@ -77,7 +77,7 @@ fn check_msg(body: &Body, expected: &str) { }; assert_eq!(alloc.provenance.ptrs.len(), 1); - let alloc_prov_id = alloc.provenance.ptrs[0].1 .0; + let alloc_prov_id = alloc.provenance.ptrs[0].1.0; let GlobalAlloc::Memory(val) = GlobalAlloc::from(alloc_prov_id) else { unreachable!() }; @@ -95,7 +95,7 @@ fn change_panic_msg(mut body: Body, new_msg: &str) -> Body { for bb in &mut body.blocks { match &mut bb.terminator.kind { TerminatorKind::Call { args, .. } => { - let new_const = Const::from_str(new_msg); + let new_const = MirConst::from_str(new_msg); args[0] = Operand::Constant(Constant { literal: new_const, span: bb.terminator.span, From 67a73f265f6eb66f0804f467a640fee45301be73 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 4 Jun 2024 11:27:54 +0000 Subject: [PATCH 12/12] bless privacy tests (only diagnostic duplication) --- .../generic_const_exprs/eval-privacy.rs | 1 + .../generic_const_exprs/eval-privacy.stderr | 13 ++++++++++++- tests/ui/privacy/where-priv-type.rs | 1 + tests/ui/privacy/where-priv-type.stderr | 13 ++++++++++++- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs index 8023b998a4099..af17a37bf23a4 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.rs @@ -15,6 +15,7 @@ where { type AssocTy = Const<{ my_const_fn(U) }>; //~^ ERROR private type + //~| ERROR private type fn assoc_fn() -> Self::AssocTy { Const } diff --git a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr index 043fa34d605ab..df0d43bef876c 100644 --- a/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr +++ b/tests/ui/const-generics/generic_const_exprs/eval-privacy.stderr @@ -7,6 +7,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -error: aborting due to 1 previous error +error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface + --> $DIR/eval-privacy.rs:16:5 + | +LL | type AssocTy = Const<{ my_const_fn(U) }>; + | ^^^^^^^^^^^^ can't leak private type +... +LL | const fn my_const_fn(val: u8) -> u8 { + | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0446`. diff --git a/tests/ui/privacy/where-priv-type.rs b/tests/ui/privacy/where-priv-type.rs index cd9cce7ec3e8d..a62feace2da26 100644 --- a/tests/ui/privacy/where-priv-type.rs +++ b/tests/ui/privacy/where-priv-type.rs @@ -74,6 +74,7 @@ where { type AssocTy = Const<{ my_const_fn(U) }>; //~^ ERROR private type + //~| ERROR private type fn assoc_fn() -> Self::AssocTy { Const } diff --git a/tests/ui/privacy/where-priv-type.stderr b/tests/ui/privacy/where-priv-type.stderr index 126330b14a63f..8ea2e17c4361b 100644 --- a/tests/ui/privacy/where-priv-type.stderr +++ b/tests/ui/privacy/where-priv-type.stderr @@ -77,6 +77,17 @@ LL | type AssocTy = Const<{ my_const_fn(U) }>; LL | const fn my_const_fn(val: u8) -> u8 { | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private -error: aborting due to 1 previous error; 5 warnings emitted +error[E0446]: private type `fn(u8) -> u8 {my_const_fn}` in public interface + --> $DIR/where-priv-type.rs:75:5 + | +LL | type AssocTy = Const<{ my_const_fn(U) }>; + | ^^^^^^^^^^^^ can't leak private type +... +LL | const fn my_const_fn(val: u8) -> u8 { + | ----------------------------------- `fn(u8) -> u8 {my_const_fn}` declared as private + | + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error: aborting due to 2 previous errors; 5 warnings emitted For more information about this error, try `rustc --explain E0446`.