From ace436743fff6dcfd21d8194acdd43a94c1611ec Mon Sep 17 00:00:00 2001 From: Gurinder Singh Date: Wed, 6 Mar 2024 16:51:17 +0530 Subject: [PATCH] Check that return type is WF in typeck Without it non-WF types could pass typeck and then later fail in MIR/const eval --- compiler/rustc_hir_typeck/src/lib.rs | 6 ++- tests/ui/const-generics/issues/issue-71202.rs | 2 +- .../const-generics/issues/issue-71202.stderr | 27 ++++++++++- tests/ui/layout/issue-84108.rs | 1 + tests/ui/layout/issue-84108.stderr | 12 ++++- .../ice-unsized-tuple-const-issue-121443.rs | 16 +++++++ ...ce-unsized-tuple-const-issue-121443.stderr | 45 +++++++++++++++++++ .../bound/on-structs-and-enums-static.rs | 1 + .../bound/on-structs-and-enums-static.stderr | 22 ++++++++- tests/ui/wf/wf-const-type.rs | 1 + tests/ui/wf/wf-const-type.stderr | 21 ++++++++- tests/ui/wf/wf-static-type.rs | 1 + tests/ui/wf/wf-static-type.stderr | 21 ++++++++- 13 files changed, 168 insertions(+), 8 deletions(-) create mode 100644 tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs create mode 100644 tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs index 70ddd6b2f4cf5..d86b4912c89bd 100644 --- a/compiler/rustc_hir_typeck/src/lib.rs +++ b/compiler/rustc_hir_typeck/src/lib.rs @@ -61,7 +61,7 @@ use rustc_hir::{HirIdMap, Node}; use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::check::check_abi; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; -use rustc_infer::traits::ObligationInspector; +use rustc_infer::traits::{ObligationCauseCode, ObligationInspector, WellFormedLoc}; use rustc_middle::query::Providers; use rustc_middle::traits; use rustc_middle::ty::{self, Ty, TyCtxt}; @@ -253,6 +253,10 @@ fn typeck_with_fallback<'tcx>( let expected_type = expected_type.unwrap_or_else(fallback); let expected_type = fcx.normalize(body.value.span, expected_type); + + let wf_code = ObligationCauseCode::WellFormed(Some(WellFormedLoc::Ty(def_id))); + fcx.register_wf_obligation(expected_type.into(), body.value.span, wf_code); + fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized); // Gather locals in statics (because of block expressions). diff --git a/tests/ui/const-generics/issues/issue-71202.rs b/tests/ui/const-generics/issues/issue-71202.rs index 57fd72b12846e..0f955414d843e 100644 --- a/tests/ui/const-generics/issues/issue-71202.rs +++ b/tests/ui/const-generics/issues/issue-71202.rs @@ -25,7 +25,7 @@ impl DataHolder { } >::VALUE - } as usize] = []; + } as usize] = []; //~ ERROR unconstrained generic constant } fn main() {} diff --git a/tests/ui/const-generics/issues/issue-71202.stderr b/tests/ui/const-generics/issues/issue-71202.stderr index 2aa9e344067bf..437b808c893c2 100644 --- a/tests/ui/const-generics/issues/issue-71202.stderr +++ b/tests/ui/const-generics/issues/issue-71202.stderr @@ -29,5 +29,30 @@ LL | | } as usize] = []; >::VALUE } as usize]:` -error: aborting due to 1 previous error +error: unconstrained generic constant + --> $DIR/issue-71202.rs:28:19 + | +LL | } as usize] = []; + | ^^ + | + = help: try adding a `where` bound using this expression: `where [(); 1 - { + trait NotCopy { + const VALUE: bool = false; + } + + impl<__Type: ?Sized> NotCopy for __Type {} + + struct IsCopy<__Type: ?Sized>(PhantomData<__Type>); + + impl<__Type> IsCopy<__Type> + where + __Type: Sized + Copy, + { + const VALUE: bool = true; + } + + >::VALUE + } as usize]:` + +error: aborting due to 2 previous errors diff --git a/tests/ui/layout/issue-84108.rs b/tests/ui/layout/issue-84108.rs index 44d6ac8db72f0..425da65b9905a 100644 --- a/tests/ui/layout/issue-84108.rs +++ b/tests/ui/layout/issue-84108.rs @@ -11,4 +11,5 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42); static BAZ: ([u8], usize) = ([], 0); //~^ 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 diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr index 58bddb069fc7d..6c168cc5fa84c 100644 --- a/tests/ui/layout/issue-84108.stderr +++ b/tests/ui/layout/issue-84108.stderr @@ -29,6 +29,16 @@ LL | static BAZ: ([u8], usize) = ([], 0); = 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:12:13 + | +LL | static BAZ: ([u8], usize) = ([], 0); + | ^^^^^^^^^^^^^ 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:12:30 | @@ -38,7 +48,7 @@ LL | static BAZ: ([u8], usize) = ([], 0); = note: expected slice `[u8]` found array `[_; 0]` -error: aborting due to 4 previous errors +error: aborting due to 5 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/trait-bounds/ice-unsized-tuple-const-issue-121443.rs b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs new file mode 100644 index 0000000000000..c3a2ab82adc6a --- /dev/null +++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.rs @@ -0,0 +1,16 @@ +// Regression test for #121443 +// Checks that no ICE occurs upon encountering +// a tuple with unsized element that is not +// the last element + +type Fn = dyn FnOnce() -> u8; + +const TEST: Fn = some_fn; +//~^ ERROR cannot find value `some_fn` in this scope +//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time +//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time +const TEST2: (Fn, u8) = (TEST, 0); +//~^ ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time +//~| ERROR the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time + +fn main() {} diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr new file mode 100644 index 0000000000000..0e92979ccd507 --- /dev/null +++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr @@ -0,0 +1,45 @@ +error[E0425]: cannot find value `some_fn` in this scope + --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18 + | +LL | const TEST: Fn = some_fn; + | ^^^^^^^ not found in this scope + +error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time + --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:13 + | +LL | const TEST: Fn = some_fn; + | ^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)` + +error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time + --> $DIR/ice-unsized-tuple-const-issue-121443.rs:8:18 + | +LL | const TEST: Fn = some_fn; + | ^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)` + = note: constant expressions must have a statically known size + +error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time + --> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:14 + | +LL | const TEST2: (Fn, u8) = (TEST, 0); + | ^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)` + = note: only the last element of a tuple may have a dynamically sized type + +error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time + --> $DIR/ice-unsized-tuple-const-issue-121443.rs:12:25 + | +LL | const TEST2: (Fn, u8) = (TEST, 0); + | ^^^^^^^^^ doesn't have a size known at compile-time + | + = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)` + = note: only the last element of a tuple may have a dynamically sized type + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0277, E0425. +For more information about an error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.rs b/tests/ui/traits/bound/on-structs-and-enums-static.rs index 066416cb362a3..d734893dd7c96 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.rs +++ b/tests/ui/traits/bound/on-structs-and-enums-static.rs @@ -8,6 +8,7 @@ struct Foo { static X: Foo = Foo { //~^ ERROR E0277 +//~| ERROR E0277 x: 1, //~ ERROR: E0277 }; diff --git a/tests/ui/traits/bound/on-structs-and-enums-static.stderr b/tests/ui/traits/bound/on-structs-and-enums-static.stderr index 28bbe00c58218..42ebcc07571f1 100644 --- a/tests/ui/traits/bound/on-structs-and-enums-static.stderr +++ b/tests/ui/traits/bound/on-structs-and-enums-static.stderr @@ -16,7 +16,25 @@ LL | struct Foo { | ^^^^^ required by this bound in `Foo` error[E0277]: the trait bound `usize: Trait` is not satisfied - --> $DIR/on-structs-and-enums-static.rs:11:8 + --> $DIR/on-structs-and-enums-static.rs:9:11 + | +LL | static X: Foo = Foo { + | ^^^^^^^^^^ the trait `Trait` is not implemented for `usize` + | +help: this trait has no implementations, consider adding one + --> $DIR/on-structs-and-enums-static.rs:1:1 + | +LL | trait Trait { + | ^^^^^^^^^^^ +note: required by a bound in `Foo` + --> $DIR/on-structs-and-enums-static.rs:5:14 + | +LL | struct Foo { + | ^^^^^ required by this bound in `Foo` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` + +error[E0277]: the trait bound `usize: Trait` is not satisfied + --> $DIR/on-structs-and-enums-static.rs:12:8 | LL | x: 1, | ^ the trait `Trait` is not implemented for `usize` @@ -32,6 +50,6 @@ note: required by a bound in `Foo` LL | struct Foo { | ^^^^^ required by this bound in `Foo` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/wf-const-type.rs b/tests/ui/wf/wf-const-type.rs index 64b0d9c8de797..3b770b4b91633 100644 --- a/tests/ui/wf/wf-const-type.rs +++ b/tests/ui/wf/wf-const-type.rs @@ -10,6 +10,7 @@ struct NotCopy; const FOO: IsCopy> = IsCopy { t: None }; //~^ ERROR E0277 //~| ERROR E0277 +//~| ERROR E0277 fn main() { } diff --git a/tests/ui/wf/wf-const-type.stderr b/tests/ui/wf/wf-const-type.stderr index d5e0f7672a6f3..d73642729ea75 100644 --- a/tests/ui/wf/wf-const-type.stderr +++ b/tests/ui/wf/wf-const-type.stderr @@ -16,6 +16,25 @@ LL + #[derive(Copy)] LL | struct NotCopy; | +error[E0277]: the trait bound `NotCopy: Copy` is not satisfied + --> $DIR/wf-const-type.rs:10:12 + | +LL | const FOO: IsCopy> = IsCopy { t: None }; + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`, which is required by `Option: Copy` + | + = note: required for `Option` to implement `Copy` +note: required by a bound in `IsCopy` + --> $DIR/wf-const-type.rs:7:17 + | +LL | struct IsCopy { t: T } + | ^^^^ required by this bound in `IsCopy` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider annotating `NotCopy` with `#[derive(Copy)]` + | +LL + #[derive(Copy)] +LL | struct NotCopy; + | + error[E0277]: the trait bound `NotCopy: Copy` is not satisfied --> $DIR/wf-const-type.rs:10:50 | @@ -34,6 +53,6 @@ LL + #[derive(Copy)] LL | struct NotCopy; | -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/wf/wf-static-type.rs b/tests/ui/wf/wf-static-type.rs index f454fe30e7750..1980c5de40c80 100644 --- a/tests/ui/wf/wf-static-type.rs +++ b/tests/ui/wf/wf-static-type.rs @@ -10,6 +10,7 @@ struct NotCopy; static FOO: IsCopy> = IsCopy { t: None }; //~^ ERROR E0277 //~| ERROR E0277 +//~| ERROR E0277 fn main() { } diff --git a/tests/ui/wf/wf-static-type.stderr b/tests/ui/wf/wf-static-type.stderr index 481173b8a269c..36234f3fd1766 100644 --- a/tests/ui/wf/wf-static-type.stderr +++ b/tests/ui/wf/wf-static-type.stderr @@ -16,6 +16,25 @@ LL + #[derive(Copy)] LL | struct NotCopy; | +error[E0277]: the trait bound `NotCopy: Copy` is not satisfied + --> $DIR/wf-static-type.rs:10:13 + | +LL | static FOO: IsCopy> = IsCopy { t: None }; + | ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`, which is required by `Option: Copy` + | + = note: required for `Option` to implement `Copy` +note: required by a bound in `IsCopy` + --> $DIR/wf-static-type.rs:7:17 + | +LL | struct IsCopy { t: T } + | ^^^^ required by this bound in `IsCopy` + = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no` +help: consider annotating `NotCopy` with `#[derive(Copy)]` + | +LL + #[derive(Copy)] +LL | struct NotCopy; + | + error[E0277]: the trait bound `NotCopy: Copy` is not satisfied --> $DIR/wf-static-type.rs:10:51 | @@ -34,6 +53,6 @@ LL + #[derive(Copy)] LL | struct NotCopy; | -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0277`.