Rollup merge of #97780 - compiler-errors:field-wfcheck-before-sized, r=jackh726
Check ADT field is well-formed before checking it is sized Fixes #96810. There is one diagnostics regression, in [`src/test/ui/generic-associated-types/bugs/issue-80626.stderr`](https://github.com/rust-lang/rust/pull/97780/files#diff-53795946378e78a0af23a10277c628ff79091c18090fdc385801ee70c1ba6963). I am not super concerned about it, since it's GAT related. We _could_ fix it, possibly by using the `FieldSized` obligation cause code instead of `BuiltinDerivedObligation`. But that would require changing `Sized` trait confirmation and the `adt_sized_constraint` query.
This commit is contained in:
commit
43dd0e2424
@ -406,7 +406,7 @@ pub enum ObligationCauseCode<'tcx> {
|
|||||||
QuestionMark,
|
QuestionMark,
|
||||||
|
|
||||||
/// Well-formed checking. If a `WellFormedLoc` is provided,
|
/// 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.
|
/// after an error occurs, in order to generate a more precise error span.
|
||||||
/// This is purely for diagnostic purposes - it is always
|
/// This is purely for diagnostic purposes - it is always
|
||||||
/// correct to use `MiscObligation` instead, or to specify
|
/// correct to use `MiscObligation` instead, or to specify
|
||||||
|
@ -990,6 +990,15 @@ fn check_type_defn<'tcx, F>(
|
|||||||
let packed = tcx.adt_def(item.def_id).repr().packed();
|
let packed = tcx.adt_def(item.def_id).repr().packed();
|
||||||
|
|
||||||
for variant in &variants {
|
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
|
// For DST, or when drop needs to copy things around, all
|
||||||
// intermediate types must be sized.
|
// intermediate types must be sized.
|
||||||
let needs_drop_copy = || {
|
let needs_drop_copy = || {
|
||||||
@ -1006,6 +1015,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 all_sized = all_sized || variant.fields.is_empty() || needs_drop_copy();
|
||||||
let unsized_len = if all_sized { 0 } else { 1 };
|
let unsized_len = if all_sized { 0 } else { 1 };
|
||||||
for (idx, field) in
|
for (idx, field) in
|
||||||
@ -1030,15 +1040,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.
|
// Explicit `enum` discriminant values must const-evaluate successfully.
|
||||||
if let Some(discr_def_id) = variant.explicit_discr {
|
if let Some(discr_def_id) = variant.explicit_discr {
|
||||||
let discr_substs = InternalSubsts::identity_for_item(tcx, discr_def_id.to_def_id());
|
let discr_substs = InternalSubsts::identity_for_item(tcx, discr_def_id.to_def_id());
|
||||||
|
@ -4,16 +4,11 @@ error[E0275]: overflow evaluating the requirement `LinkedList<A>: Sized`
|
|||||||
LL | Next(A::Allocated<Self>)
|
LL | Next(A::Allocated<Self>)
|
||||||
| ^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^
|
||||||
|
|
|
|
||||||
= note: no field of an enum variant may have a dynamically sized type
|
note: required by a bound in `Allocator::Allocated`
|
||||||
= help: change the field's type to have a statically known size
|
--> $DIR/issue-80626.rs:9:20
|
||||||
help: borrowed types always have a statically known size
|
|
||||||
|
|
|
|
||||||
LL | Next(&A::Allocated<Self>)
|
LL | type Allocated<T>;
|
||||||
| +
|
| ^ required by this bound in `Allocator::Allocated`
|
||||||
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
|
||||||
|
|
|
||||||
LL | Next(Box<A::Allocated<Self>>)
|
|
||||||
| ++++ +
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
@ -1,28 +1,18 @@
|
|||||||
error[E0277]: the trait bound `T: Pointee` is not satisfied in `PtrComponents<T>`
|
error[E0277]: the trait bound `T: Pointee` is not satisfied
|
||||||
--> $DIR/issue-81199.rs:5:17
|
--> $DIR/issue-81199.rs:5:17
|
||||||
|
|
|
|
||||||
LL | components: PtrComponents<T>,
|
LL | components: PtrComponents<T>,
|
||||||
| ^^^^^^^^^^^^^^^^ within `PtrComponents<T>`, 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<T>`
|
note: required by a bound in `PtrComponents`
|
||||||
--> $DIR/issue-81199.rs:10:8
|
--> $DIR/issue-81199.rs:10:25
|
||||||
|
|
|
|
||||||
LL | struct PtrComponents<T: Pointee + ?Sized> {
|
LL | struct PtrComponents<T: Pointee + ?Sized> {
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^ required by this bound in `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
|
|
||||||
help: consider further restricting this bound
|
help: consider further restricting this bound
|
||||||
|
|
|
|
||||||
LL | union PtrRepr<T: ?Sized + Pointee> {
|
LL | union PtrRepr<T: ?Sized + Pointee> {
|
||||||
| +++++++++
|
| +++++++++
|
||||||
help: borrowed types always have a statically known size
|
|
||||||
|
|
|
||||||
LL | components: &PtrComponents<T>,
|
|
||||||
| +
|
|
||||||
help: the `Box` type always has a statically known size and allocates its contents in the heap
|
|
||||||
|
|
|
||||||
LL | components: Box<PtrComponents<T>>,
|
|
||||||
| ++++ +
|
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
12
src/test/ui/wf/issue-96810.rs
Normal file
12
src/test/ui/wf/issue-96810.rs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
struct S<T: Tr>(T::Assoc);
|
||||||
|
|
||||||
|
trait Tr {
|
||||||
|
type Assoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Hoge<K> {
|
||||||
|
s: S<K>, //~ ERROR the trait bound `K: Tr` is not satisfied
|
||||||
|
a: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
19
src/test/ui/wf/issue-96810.stderr
Normal file
19
src/test/ui/wf/issue-96810.stderr
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
error[E0277]: the trait bound `K: Tr` is not satisfied
|
||||||
|
--> $DIR/issue-96810.rs:8:8
|
||||||
|
|
|
||||||
|
LL | s: S<K>,
|
||||||
|
| ^^^^ 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: Tr>(T::Assoc);
|
||||||
|
| ^^ required by this bound in `S`
|
||||||
|
help: consider restricting type parameter `K`
|
||||||
|
|
|
||||||
|
LL | struct Hoge<K: Tr> {
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
Loading…
x
Reference in New Issue
Block a user