From 18906754ccee76cebf92803c487942465c7f79a4 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Wed, 31 Jul 2024 20:33:48 -0700 Subject: [PATCH 1/3] Add test for WF check of implied unsizing in struct fields Note that the test output is currently *incorrect*. We should be emitting an error at the use site too, not just at the definition. This is partly for UI reasons, but mainly to fix a related ICE where a const generic body is not tainted with an error since no usage error is reported. --- .../structs/field-implied-unsizing-wfcheck.rs | 10 ++++++++ .../field-implied-unsizing-wfcheck.stderr | 23 +++++++++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 tests/ui/structs/field-implied-unsizing-wfcheck.rs create mode 100644 tests/ui/structs/field-implied-unsizing-wfcheck.stderr diff --git a/tests/ui/structs/field-implied-unsizing-wfcheck.rs b/tests/ui/structs/field-implied-unsizing-wfcheck.rs new file mode 100644 index 00000000000..24da4b5e89d --- /dev/null +++ b/tests/ui/structs/field-implied-unsizing-wfcheck.rs @@ -0,0 +1,10 @@ +struct Foo { + nested: &'static Bar, + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +} + +struct Bar(T); + +fn main() { + let x = Foo { nested: &Bar(4) }; +} diff --git a/tests/ui/structs/field-implied-unsizing-wfcheck.stderr b/tests/ui/structs/field-implied-unsizing-wfcheck.stderr new file mode 100644 index 00000000000..c47918c7d16 --- /dev/null +++ b/tests/ui/structs/field-implied-unsizing-wfcheck.stderr @@ -0,0 +1,23 @@ +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:2:13 + | +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error: aborting due to 1 previous error + +For more information about this error, try `rustc --explain E0277`. From 9479792cb4e6bdb0eba18d91af5ba3096c9007df Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 5 Aug 2024 17:26:46 -0700 Subject: [PATCH 2/3] WF-check struct field types at construction site Rustc of course already WF-checked the field types at the definition site, but for error tainting of consts to work properly, there needs to be an error emitted at the use site. Previously, with no use-site error, we proceeded with CTFE and ran into ICEs since we are running code with type errors. Emitting use-site errors also brings struct-like constructors more in line with fn-like constructors since they already emit use-site errors for WF issues. --- compiler/rustc_hir_typeck/src/expr.rs | 9 + tests/crashes/126272.rs | 28 --- tests/crashes/127299.rs | 12 -- .../unsizing-wfcheck-issue-126272.rs | 28 +++ .../unsizing-wfcheck-issue-126272.stderr | 160 ++++++++++++++++++ .../generic_const_exprs/no_where_clause.rs | 1 + .../no_where_clause.stderr | 13 +- .../generic-associated-types/issue-71176.rs | 2 +- .../issue-71176.stderr | 18 +- tests/ui/issues/issue-19380.rs | 1 + tests/ui/issues/issue-19380.stderr | 25 ++- .../statics/unsizing-wfcheck-issue-127299.rs | 17 ++ .../unsizing-wfcheck-issue-127299.stderr | 87 ++++++++++ .../structs/field-implied-unsizing-wfcheck.rs | 1 + .../field-implied-unsizing-wfcheck.stderr | 22 ++- ...missing-bound-in-derive-copy-impl-2.stderr | 10 +- .../missing-bound-in-derive-copy-impl.stderr | 10 +- 17 files changed, 387 insertions(+), 57 deletions(-) delete mode 100644 tests/crashes/126272.rs delete mode 100644 tests/crashes/127299.rs create mode 100644 tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs create mode 100644 tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr create mode 100644 tests/ui/statics/unsizing-wfcheck-issue-127299.rs create mode 100644 tests/ui/statics/unsizing-wfcheck-issue-127299.stderr diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index e54f9486f6a..d6ff0cb9462 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1736,6 +1736,15 @@ fn check_expr_struct_fields( Ty::new_error(tcx, guar) }; + // Check that the expected field type is WF. Otherwise, we emit no use-site error + // in the case of coercions for non-WF fields, which leads to incorrect error + // tainting. See issue #126272. + self.register_wf_obligation( + field_type.into(), + field.expr.span, + ObligationCauseCode::WellFormed(None), + ); + // Make sure to give a type to the field even if there's // an error, so we can continue type-checking. let ty = self.check_expr_with_hint(field.expr, field_type); diff --git a/tests/crashes/126272.rs b/tests/crashes/126272.rs deleted file mode 100644 index 3412c7d8f0f..00000000000 --- a/tests/crashes/126272.rs +++ /dev/null @@ -1,28 +0,0 @@ -//@ known-bug: rust-lang/rust#126272 - -#![feature(adt_const_params)] -#![allow(incomplete_features)] - -use std::marker::ConstParamTy; - -#[derive(Debug, PartialEq, Eq, ConstParamTy)] -struct Foo { - value: i32, - nested: &'static Bar, -} - -#[derive(Debug, PartialEq, Eq, ConstParamTy)] -struct Bar(T); - -struct Test; - -fn main() { - let x: Test< - { - Foo { - value: 3, - nested: &Bar(4), - } - }, - > = Test; -} diff --git a/tests/crashes/127299.rs b/tests/crashes/127299.rs deleted file mode 100644 index 7eb78387997..00000000000 --- a/tests/crashes/127299.rs +++ /dev/null @@ -1,12 +0,0 @@ -//@ known-bug: rust-lang/rust#127299 -trait Qux { - fn bar() -> i32; -} - -pub struct Lint { - pub desc: &'static Qux, -} - -static FOO: &Lint = &Lint { desc: "desc" }; - -fn main() {} diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs new file mode 100644 index 00000000000..311f507d3c7 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.rs @@ -0,0 +1,28 @@ +// This ensures we don't ICE in situations like rust-lang/rust#126272. + +#![feature(adt_const_params)] +#![allow(incomplete_features)] + +use std::marker::ConstParamTy; + +#[derive(Debug, PartialEq, Eq, ConstParamTy)] +//~^ ERROR the trait `ConstParamTy_` +//~| ERROR the trait `ConstParamTy_` +struct Foo { + nested: &'static Bar, + //~^ ERROR the size for values + //~| ERROR the size for values + //~| ERROR binary operation `==` cannot + //~| ERROR the trait bound `dyn Debug: Eq` + //~| ERROR the size for values +} + +#[derive(Debug, PartialEq, Eq, ConstParamTy)] +struct Bar(T); + +struct Test; + +fn main() { + let x: Test<{ Foo { nested: &Bar(4) } }> = Test; + //~^ ERROR the size for values +} diff --git a/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr new file mode 100644 index 00000000000..1c30aa68e85 --- /dev/null +++ b/tests/ui/const-generics/adt_const_params/unsizing-wfcheck-issue-126272.stderr @@ -0,0 +1,160 @@ +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 + | +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type + --> $DIR/unsizing-wfcheck-issue-126272.rs:8:32 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | ^^^^^^^^^^^^ +... +LL | nested: &'static Bar, + | ----------------------------------------- this field does not implement `ConstParamTy_` + | + = note: this error originates in the derive macro `ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0204]: the trait `ConstParamTy_` cannot be implemented for this type + --> $DIR/unsizing-wfcheck-issue-126272.rs:8:32 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | ^^^^^^^^^^^^ +... +LL | nested: &'static Bar, + | ----------------------------------------- this field does not implement `ConstParamTy_` + | +note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): Eq` + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 + | +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): Sized` + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 + | +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +note: the `ConstParamTy_` impl for `&'static Bar<(dyn Debug + 'static)>` requires that `(dyn Debug + 'static): UnsizedConstParamTy` + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:13 + | +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: this error originates in the derive macro `ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | ----- in this derive macro expansion +... +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)`, which is required by `&&'static Bar<(dyn Debug + 'static)>: Debug` + = help: the trait `Debug` is implemented for `Bar` +note: required for `Bar<(dyn Debug + 'static)>` to implement `Debug` + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:10 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | ^^^^^ +LL | struct Bar(T); + | - unsatisfied trait bound introduced in this `derive` macro + = note: 2 redundant requirements hidden + = note: required for `&&'static Bar<(dyn Debug + 'static)>` to implement `Debug` + = note: required for the cast from `&&&'static Bar<(dyn Debug + 'static)>` to `&dyn Debug` + = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0369]: binary operation `==` cannot be applied to type `&Bar` + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | --------- in this derive macro expansion +... +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the derive macro `PartialEq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the trait bound `dyn Debug: Eq` is not satisfied + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | -- in this derive macro expansion +... +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `dyn Debug`, which is required by `&'static Bar: Eq` + | + = help: the trait `Eq` is implemented for `Bar` +note: required for `Bar` to implement `Eq` + --> $DIR/unsizing-wfcheck-issue-126272.rs:20:28 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | ^^ unsatisfied trait bound introduced in this `derive` macro + = note: 1 redundant requirement hidden + = note: required for `&'static Bar` to implement `Eq` +note: required by a bound in `AssertParamIsEq` + --> $SRC_DIR/core/src/cmp.rs:LL:COL + = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `dyn Debug` cannot be known at compilation time + --> $DIR/unsizing-wfcheck-issue-126272.rs:12:5 + | +LL | #[derive(Debug, PartialEq, Eq, ConstParamTy)] + | -- in this derive macro expansion +... +LL | nested: &'static Bar, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `dyn Debug` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/unsizing-wfcheck-issue-126272.rs:26:33 + | +LL | let x: Test<{ Foo { nested: &Bar(4) } }> = Test; + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/unsizing-wfcheck-issue-126272.rs:21:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0204, E0277, E0369. +For more information about an error, try `rustc --explain E0204`. diff --git a/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs b/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs index 77cce66e4ec..53230469491 100644 --- a/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs +++ b/tests/ui/const-generics/generic_const_exprs/no_where_clause.rs @@ -17,6 +17,7 @@ pub fn new() -> Self { a: [0.; N], b: [0.; complex_maths(N)], //~^ ERROR: unconstrained generic constant + //~| ERROR: unconstrained generic constant } } } diff --git a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr index a2680eac039..88fc68a4d1b 100644 --- a/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr +++ b/tests/ui/const-generics/generic_const_exprs/no_where_clause.stderr @@ -9,6 +9,17 @@ help: try adding a `where` bound LL | pub struct Example where [(); complex_maths(N)]: { | +++++++++++++++++++++++++++++ +error: unconstrained generic constant + --> $DIR/no_where_clause.rs:18:10 + | +LL | b: [0.; complex_maths(N)], + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try adding a `where` bound + | +LL | pub fn new() -> Self where [(); complex_maths(N)]: { + | +++++++++++++++++++++++++++++ + error: unconstrained generic constant --> $DIR/no_where_clause.rs:18:15 | @@ -20,5 +31,5 @@ help: try adding a `where` bound LL | pub fn new() -> Self where [(); complex_maths(N)]: { | +++++++++++++++++++++++++++++ -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors diff --git a/tests/ui/generic-associated-types/issue-71176.rs b/tests/ui/generic-associated-types/issue-71176.rs index e58b6f6091e..b33fda8e154 100644 --- a/tests/ui/generic-associated-types/issue-71176.rs +++ b/tests/ui/generic-associated-types/issue-71176.rs @@ -16,6 +16,6 @@ struct Holder { fn main() { Holder { - inner: Box::new(()), + inner: Box::new(()), //~ ERROR: the trait `Provider` cannot be made into an object }; } diff --git a/tests/ui/generic-associated-types/issue-71176.stderr b/tests/ui/generic-associated-types/issue-71176.stderr index a1913bb618b..9f83c162c02 100644 --- a/tests/ui/generic-associated-types/issue-71176.stderr +++ b/tests/ui/generic-associated-types/issue-71176.stderr @@ -64,7 +64,23 @@ LL | type A<'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 +error[E0038]: the trait `Provider` cannot be made into an object + --> $DIR/issue-71176.rs:19:16 + | +LL | inner: Box::new(()), + | ^^^^^^^^^^^^ `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 5 previous errors Some errors have detailed explanations: E0038, E0107. For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/issues/issue-19380.rs b/tests/ui/issues/issue-19380.rs index fce737cba18..8b3fe4d2b09 100644 --- a/tests/ui/issues/issue-19380.rs +++ b/tests/ui/issues/issue-19380.rs @@ -15,5 +15,6 @@ struct Bar { const FOO : Foo = Foo; const BAR : Bar = Bar { foos: &[&FOO]}; //~^ ERROR E0038 +//~| ERROR E0038 fn main() { } diff --git a/tests/ui/issues/issue-19380.stderr b/tests/ui/issues/issue-19380.stderr index f6244d9d44f..1d7aa6bd459 100644 --- a/tests/ui/issues/issue-19380.stderr +++ b/tests/ui/issues/issue-19380.stderr @@ -45,6 +45,29 @@ help: alternatively, consider constraining `qiz` so it does not apply to trait o LL | fn qiz() where Self: Sized; | +++++++++++++++++ -error: aborting due to 2 previous errors +error[E0038]: the trait `Qiz` cannot be made into an object + --> $DIR/issue-19380.rs:16:31 + | +LL | const BAR : Bar = Bar { foos: &[&FOO]}; + | ^^^^^^^ `Qiz` 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-19380.rs:2:6 + | +LL | trait Qiz { + | --- this trait cannot be made into an object... +LL | fn qiz(); + | ^^^ ...because associated function `qiz` has no `self` parameter + = help: only type `Foo` implements the trait, consider using it directly instead +help: consider turning `qiz` into a method by giving it a `&self` argument + | +LL | fn qiz(&self); + | +++++ +help: alternatively, consider constraining `qiz` so it does not apply to trait objects + | +LL | fn qiz() where Self: Sized; + | +++++++++++++++++ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/statics/unsizing-wfcheck-issue-127299.rs b/tests/ui/statics/unsizing-wfcheck-issue-127299.rs new file mode 100644 index 00000000000..cd15be54ec7 --- /dev/null +++ b/tests/ui/statics/unsizing-wfcheck-issue-127299.rs @@ -0,0 +1,17 @@ +// This ensures we don't ICE in situations like rust-lang/rust#127299. + +trait Qux { + fn bar() -> i32; +} + +pub struct Lint { + pub desc: &'static dyn Qux, + //~^ ERROR cannot be made into an object +} + +static FOO: &Lint = &Lint { desc: "desc" }; +//~^ ERROR cannot be shared between threads safely +//~| ERROR cannot be made into an object +//~| ERROR cannot be made into an object + +fn main() {} diff --git a/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr b/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr new file mode 100644 index 00000000000..49e8d87f354 --- /dev/null +++ b/tests/ui/statics/unsizing-wfcheck-issue-127299.stderr @@ -0,0 +1,87 @@ +error[E0038]: the trait `Qux` cannot be made into an object + --> $DIR/unsizing-wfcheck-issue-127299.rs:8:24 + | +LL | pub desc: &'static dyn Qux, + | ^^^^^^^ `Qux` 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/unsizing-wfcheck-issue-127299.rs:4:8 + | +LL | trait Qux { + | --- this trait cannot be made into an object... +LL | fn bar() -> i32; + | ^^^ ...because associated function `bar` has no `self` parameter +help: consider turning `bar` into a method by giving it a `&self` argument + | +LL | fn bar(&self) -> i32; + | +++++ +help: alternatively, consider constraining `bar` so it does not apply to trait objects + | +LL | fn bar() -> i32 where Self: Sized; + | +++++++++++++++++ + +error[E0277]: `(dyn Qux + 'static)` cannot be shared between threads safely + --> $DIR/unsizing-wfcheck-issue-127299.rs:12:13 + | +LL | static FOO: &Lint = &Lint { desc: "desc" }; + | ^^^^^ `(dyn Qux + 'static)` cannot be shared between threads safely + | + = help: within `&'static Lint`, the trait `Sync` is not implemented for `(dyn Qux + 'static)`, which is required by `&'static Lint: Sync` + = note: required because it appears within the type `&'static (dyn Qux + 'static)` +note: required because it appears within the type `Lint` + --> $DIR/unsizing-wfcheck-issue-127299.rs:7:12 + | +LL | pub struct Lint { + | ^^^^ + = note: required because it appears within the type `&'static Lint` + = note: shared static variables must have a type that implements `Sync` + +error[E0038]: the trait `Qux` cannot be made into an object + --> $DIR/unsizing-wfcheck-issue-127299.rs:12:35 + | +LL | static FOO: &Lint = &Lint { desc: "desc" }; + | ^^^^^^ `Qux` 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/unsizing-wfcheck-issue-127299.rs:4:8 + | +LL | trait Qux { + | --- this trait cannot be made into an object... +LL | fn bar() -> i32; + | ^^^ ...because associated function `bar` has no `self` parameter + = note: required for the cast from `&'static str` to `&'static (dyn Qux + 'static)` +help: consider turning `bar` into a method by giving it a `&self` argument + | +LL | fn bar(&self) -> i32; + | +++++ +help: alternatively, consider constraining `bar` so it does not apply to trait objects + | +LL | fn bar() -> i32 where Self: Sized; + | +++++++++++++++++ + +error[E0038]: the trait `Qux` cannot be made into an object + --> $DIR/unsizing-wfcheck-issue-127299.rs:12:35 + | +LL | static FOO: &Lint = &Lint { desc: "desc" }; + | ^^^^^^ `Qux` 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/unsizing-wfcheck-issue-127299.rs:4:8 + | +LL | trait Qux { + | --- this trait cannot be made into an object... +LL | fn bar() -> i32; + | ^^^ ...because associated function `bar` has no `self` parameter +help: consider turning `bar` into a method by giving it a `&self` argument + | +LL | fn bar(&self) -> i32; + | +++++ +help: alternatively, consider constraining `bar` so it does not apply to trait objects + | +LL | fn bar() -> i32 where Self: Sized; + | +++++++++++++++++ + +error: aborting due to 4 previous errors + +Some errors have detailed explanations: E0038, E0277. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/structs/field-implied-unsizing-wfcheck.rs b/tests/ui/structs/field-implied-unsizing-wfcheck.rs index 24da4b5e89d..981ff138de3 100644 --- a/tests/ui/structs/field-implied-unsizing-wfcheck.rs +++ b/tests/ui/structs/field-implied-unsizing-wfcheck.rs @@ -7,4 +7,5 @@ struct Foo { fn main() { let x = Foo { nested: &Bar(4) }; + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time } diff --git a/tests/ui/structs/field-implied-unsizing-wfcheck.stderr b/tests/ui/structs/field-implied-unsizing-wfcheck.stderr index c47918c7d16..79198c86141 100644 --- a/tests/ui/structs/field-implied-unsizing-wfcheck.stderr +++ b/tests/ui/structs/field-implied-unsizing-wfcheck.stderr @@ -18,6 +18,26 @@ LL | struct Bar(T); | | | this could be changed to `T: ?Sized`... -error: aborting due to 1 previous error +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:9:27 + | +LL | let x = Foo { nested: &Bar(4) }; + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr index a2a78ddc705..db16fff826f 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl-2.stderr @@ -44,15 +44,13 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct AABB { LL | pub loc: Vector2, - | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2: Clone` + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | -note: required for `Vector2` to implement `Clone` - --> $DIR/missing-bound-in-derive-copy-impl-2.rs:4:23 +note: required by a bound in `Vector2` + --> $DIR/missing-bound-in-derive-copy-impl-2.rs:5:31 | -LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ^^^^ required by this bound in `Vector2` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | diff --git a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr index 2ae0871b815..cf383b5c8ff 100644 --- a/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr +++ b/tests/ui/suggestions/missing-bound-in-derive-copy-impl.stderr @@ -95,15 +95,13 @@ LL | #[derive(Debug, Copy, Clone)] | ----- in this derive macro expansion LL | pub struct AABB { LL | pub loc: Vector2, - | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K`, which is required by `Vector2: Clone` + | ^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `K` | -note: required for `Vector2` to implement `Clone` - --> $DIR/missing-bound-in-derive-copy-impl.rs:3:23 +note: required by a bound in `Vector2` + --> $DIR/missing-bound-in-derive-copy-impl.rs:4:31 | -LL | #[derive(Debug, Copy, Clone)] - | ^^^^^ LL | pub struct Vector2 { - | ---- unsatisfied trait bound introduced in this `derive` macro + | ^^^^ required by this bound in `Vector2` = note: this error originates in the derive macro `Clone` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `K` | From 2f4603b7158025119f45d905d665291b67d3e43d Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Mon, 5 Aug 2024 17:56:50 -0700 Subject: [PATCH 3/3] Test more cases of WF-checking for fields --- .../structs/field-implied-unsizing-wfcheck.rs | 25 +++- .../field-implied-unsizing-wfcheck.stderr | 136 ++++++++++++++++-- 2 files changed, 151 insertions(+), 10 deletions(-) diff --git a/tests/ui/structs/field-implied-unsizing-wfcheck.rs b/tests/ui/structs/field-implied-unsizing-wfcheck.rs index 981ff138de3..a46c9b5a68b 100644 --- a/tests/ui/structs/field-implied-unsizing-wfcheck.rs +++ b/tests/ui/structs/field-implied-unsizing-wfcheck.rs @@ -1,11 +1,32 @@ -struct Foo { +struct FooStruct { nested: &'static Bar, //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time } +struct FooTuple(&'static Bar); +//~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + +enum FooEnum1 { + Struct { nested: &'static Bar }, + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +} + +enum FooEnum2 { + Tuple(&'static Bar), + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time +} + struct Bar(T); fn main() { - let x = Foo { nested: &Bar(4) }; + // Ensure there's an error at the construction site, for error tainting purposes. + + FooStruct { nested: &Bar(4) }; + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + FooTuple(&Bar(4)); + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + FooEnum1::Struct { nested: &Bar(4) }; + //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + FooEnum2::Tuple(&Bar(4)); //~^ ERROR the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time } diff --git a/tests/ui/structs/field-implied-unsizing-wfcheck.stderr b/tests/ui/structs/field-implied-unsizing-wfcheck.stderr index 79198c86141..47d486ffa33 100644 --- a/tests/ui/structs/field-implied-unsizing-wfcheck.stderr +++ b/tests/ui/structs/field-implied-unsizing-wfcheck.stderr @@ -6,12 +6,12 @@ LL | nested: &'static Bar, | = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` note: required by an implicit `Sized` bound in `Bar` - --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 | LL | struct Bar(T); | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` - --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 | LL | struct Bar(T); | ^ - ...if indirection were used here: `Box` @@ -19,25 +19,145 @@ LL | struct Bar(T); | this could be changed to `T: ?Sized`... error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time - --> $DIR/field-implied-unsizing-wfcheck.rs:9:27 + --> $DIR/field-implied-unsizing-wfcheck.rs:6:17 | -LL | let x = Foo { nested: &Bar(4) }; - | ^^^^^^^ doesn't have a size known at compile-time +LL | struct FooTuple(&'static Bar); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time | = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` note: required by an implicit `Sized` bound in `Bar` - --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 | LL | struct Bar(T); | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` - --> $DIR/field-implied-unsizing-wfcheck.rs:6:12 + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 | LL | struct Bar(T); | ^ - ...if indirection were used here: `Box` | | | this could be changed to `T: ?Sized`... -error: aborting due to 2 previous errors +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:10:22 + | +LL | Struct { nested: &'static Bar }, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:15:11 + | +LL | Tuple(&'static Bar), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:24:25 + | +LL | FooStruct { nested: &Bar(4) }; + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:26:14 + | +LL | FooTuple(&Bar(4)); + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:28:32 + | +LL | FooEnum1::Struct { nested: &Bar(4) }; + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error[E0277]: the size for values of type `(dyn Debug + 'static)` cannot be known at compilation time + --> $DIR/field-implied-unsizing-wfcheck.rs:30:21 + | +LL | FooEnum2::Tuple(&Bar(4)); + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn Debug + 'static)` +note: required by an implicit `Sized` bound in `Bar` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ required by the implicit `Sized` requirement on this type parameter in `Bar` +help: you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box` + --> $DIR/field-implied-unsizing-wfcheck.rs:19:12 + | +LL | struct Bar(T); + | ^ - ...if indirection were used here: `Box` + | | + | this could be changed to `T: ?Sized`... + +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0277`.