From c1f4f980f4706365d56136f8761537f8e9b56bb4 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sun, 5 Jun 2022 23:04:37 -0700 Subject: [PATCH] Do wfcheck on ADT field before Sized check --- compiler/rustc_middle/src/traits/mod.rs | 2 +- compiler/rustc_typeck/src/check/wfcheck.rs | 19 +++++++++--------- .../bugs/issue-80626.stderr | 13 ++++-------- src/test/ui/union/issue-81199.stderr | 20 +++++-------------- src/test/ui/wf/issue-96810.rs | 12 +++++++++++ src/test/ui/wf/issue-96810.stderr | 19 ++++++++++++++++++ 6 files changed, 51 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/wf/issue-96810.rs create mode 100644 src/test/ui/wf/issue-96810.stderr diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs index 4006b2fcf177a..c963dc1689380 100644 --- a/compiler/rustc_middle/src/traits/mod.rs +++ b/compiler/rustc_middle/src/traits/mod.rs @@ -403,7 +403,7 @@ pub enum ObligationCauseCode<'tcx> { QuestionMark, /// Well-formed checking. If a `WellFormedLoc` is provided, - /// then it will be used to eprform HIR-based wf checking + /// then it will be used to perform HIR-based wf checking /// after an error occurs, in order to generate a more precise error span. /// This is purely for diagnostic purposes - it is always /// correct to use `MiscObligation` instead, or to specify diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 20ef97c085f18..e6c21608c8ae2 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -1008,6 +1008,15 @@ fn check_type_defn<'tcx, F>( let packed = tcx.adt_def(item.def_id).repr().packed(); for variant in &variants { + // All field types must be well-formed. + for field in &variant.fields { + fcx.register_wf_obligation( + field.ty.into(), + field.span, + ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(field.def_id))), + ) + } + // For DST, or when drop needs to copy things around, all // intermediate types must be sized. let needs_drop_copy = || { @@ -1024,6 +1033,7 @@ fn check_type_defn<'tcx, F>( } } }; + // All fields (except for possibly the last) should be sized. let all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy(); let unsized_len = if all_sized { 0 } else { 1 }; for (idx, field) in @@ -1048,15 +1058,6 @@ fn check_type_defn<'tcx, F>( ); } - // All field types must be well-formed. - for field in &variant.fields { - fcx.register_wf_obligation( - field.ty.into(), - field.span, - ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(field.def_id))), - ) - } - // Explicit `enum` discriminant values must const-evaluate successfully. if let Some(discr_def_id) = variant.explicit_discr { let discr_substs = InternalSubsts::identity_for_item(tcx, discr_def_id.to_def_id()); diff --git a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr index 8b0cc78e99949..487b83dfa3fcc 100644 --- a/src/test/ui/generic-associated-types/bugs/issue-80626.stderr +++ b/src/test/ui/generic-associated-types/bugs/issue-80626.stderr @@ -4,16 +4,11 @@ error[E0275]: overflow evaluating the requirement `LinkedList: Sized` LL | Next(A::Allocated) | ^^^^^^^^^^^^^^^^^^ | - = note: no field of an enum variant may have a dynamically sized type - = help: change the field's type to have a statically known size -help: borrowed types always have a statically known size +note: required by a bound in `Allocator::Allocated` + --> $DIR/issue-80626.rs:9:20 | -LL | Next(&A::Allocated) - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | Next(Box>) - | ++++ + +LL | type Allocated; + | ^ required by this bound in `Allocator::Allocated` error: aborting due to previous error diff --git a/src/test/ui/union/issue-81199.stderr b/src/test/ui/union/issue-81199.stderr index f26bfe3a0b060..5bb98675361a0 100644 --- a/src/test/ui/union/issue-81199.stderr +++ b/src/test/ui/union/issue-81199.stderr @@ -1,28 +1,18 @@ -error[E0277]: the trait bound `T: Pointee` is not satisfied in `PtrComponents` +error[E0277]: the trait bound `T: Pointee` is not satisfied --> $DIR/issue-81199.rs:5:17 | LL | components: PtrComponents, - | ^^^^^^^^^^^^^^^^ within `PtrComponents`, the trait `Pointee` is not implemented for `T` + | ^^^^^^^^^^^^^^^^ the trait `Pointee` is not implemented for `T` | -note: required because it appears within the type `PtrComponents` - --> $DIR/issue-81199.rs:10:8 +note: required by a bound in `PtrComponents` + --> $DIR/issue-81199.rs:10:25 | LL | struct PtrComponents { - | ^^^^^^^^^^^^^ - = note: no field of a union may have a dynamically sized type - = help: change the field's type to have a statically known size + | ^^^^^^^ required by this bound in `PtrComponents` help: consider further restricting this bound | LL | union PtrRepr { | +++++++++ -help: borrowed types always have a statically known size - | -LL | components: &PtrComponents, - | + -help: the `Box` type always has a statically known size and allocates its contents in the heap - | -LL | components: Box>, - | ++++ + error: aborting due to previous error diff --git a/src/test/ui/wf/issue-96810.rs b/src/test/ui/wf/issue-96810.rs new file mode 100644 index 0000000000000..c2948086b200b --- /dev/null +++ b/src/test/ui/wf/issue-96810.rs @@ -0,0 +1,12 @@ +struct S(T::Assoc); + +trait Tr { + type Assoc; +} + +struct Hoge { + s: S, //~ ERROR the trait bound `K: Tr` is not satisfied + a: u32, +} + +fn main() {} diff --git a/src/test/ui/wf/issue-96810.stderr b/src/test/ui/wf/issue-96810.stderr new file mode 100644 index 0000000000000..1407e62b1e139 --- /dev/null +++ b/src/test/ui/wf/issue-96810.stderr @@ -0,0 +1,19 @@ +error[E0277]: the trait bound `K: Tr` is not satisfied + --> $DIR/issue-96810.rs:8:8 + | +LL | s: S, + | ^^^^ the trait `Tr` is not implemented for `K` + | +note: required by a bound in `S` + --> $DIR/issue-96810.rs:1:13 + | +LL | struct S(T::Assoc); + | ^^ required by this bound in `S` +help: consider restricting type parameter `K` + | +LL | struct Hoge { + | ++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.