Check that return type is WF in typeck

Without it non-WF types could pass typeck and then
later fail in MIR/const eval
This commit is contained in:
Gurinder Singh 2024-03-06 16:51:17 +05:30
parent a09d91b04a
commit ace436743f
13 changed files with 168 additions and 8 deletions

View File

@ -61,7 +61,7 @@ use rustc_hir::{HirIdMap, Node};
use rustc_hir_analysis::astconv::AstConv; use rustc_hir_analysis::astconv::AstConv;
use rustc_hir_analysis::check::check_abi; use rustc_hir_analysis::check::check_abi;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; 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::query::Providers;
use rustc_middle::traits; use rustc_middle::traits;
use rustc_middle::ty::{self, Ty, TyCtxt}; 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 = expected_type.unwrap_or_else(fallback);
let expected_type = fcx.normalize(body.value.span, expected_type); 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); fcx.require_type_is_sized(expected_type, body.value.span, traits::ConstSized);
// Gather locals in statics (because of block expressions). // Gather locals in statics (because of block expressions).

View File

@ -25,7 +25,7 @@ impl<T: Copy> DataHolder<T> {
} }
<IsCopy<T>>::VALUE <IsCopy<T>>::VALUE
} as usize] = []; } as usize] = []; //~ ERROR unconstrained generic constant
} }
fn main() {} fn main() {}

View File

@ -29,5 +29,30 @@ LL | | } as usize] = [];
<IsCopy<T>>::VALUE <IsCopy<T>>::VALUE
} as usize]:` } 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;
}
<IsCopy<T>>::VALUE
} as usize]:`
error: aborting due to 2 previous errors

View File

@ -11,4 +11,5 @@ const BAR: (&Path, [u8], usize) = ("hello", [], 42);
static BAZ: ([u8], usize) = ([], 0); 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 the size for values of type `[u8]` cannot be known at compilation time
//~| ERROR mismatched types //~| ERROR mismatched types

View File

@ -29,6 +29,16 @@ LL | static BAZ: ([u8], usize) = ([], 0);
= help: the trait `Sized` is not implemented for `[u8]` = help: the trait `Sized` is not implemented for `[u8]`
= note: only the last element of a tuple may have a dynamically sized type = 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 error[E0308]: mismatched types
--> $DIR/issue-84108.rs:12:30 --> $DIR/issue-84108.rs:12:30
| |
@ -38,7 +48,7 @@ LL | static BAZ: ([u8], usize) = ([], 0);
= note: expected slice `[u8]` = note: expected slice `[u8]`
found array `[_; 0]` 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. Some errors have detailed explanations: E0277, E0308, E0412.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.

View File

@ -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() {}

View File

@ -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`.

View File

@ -8,6 +8,7 @@ struct Foo<T:Trait> {
static X: Foo<usize> = Foo { static X: Foo<usize> = Foo {
//~^ ERROR E0277 //~^ ERROR E0277
//~| ERROR E0277
x: 1, //~ ERROR: E0277 x: 1, //~ ERROR: E0277
}; };

View File

@ -16,7 +16,25 @@ LL | struct Foo<T:Trait> {
| ^^^^^ required by this bound in `Foo` | ^^^^^ required by this bound in `Foo`
error[E0277]: the trait bound `usize: Trait` is not satisfied 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<usize> = 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<T:Trait> {
| ^^^^^ 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, LL | x: 1,
| ^ the trait `Trait` is not implemented for `usize` | ^ the trait `Trait` is not implemented for `usize`
@ -32,6 +50,6 @@ note: required by a bound in `Foo`
LL | struct Foo<T:Trait> { LL | struct Foo<T:Trait> {
| ^^^^^ required by this bound in `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`. For more information about this error, try `rustc --explain E0277`.

View File

@ -10,6 +10,7 @@ struct NotCopy;
const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None }; const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
//~^ ERROR E0277 //~^ ERROR E0277
//~| ERROR E0277 //~| ERROR E0277
//~| ERROR E0277
fn main() { } fn main() { }

View File

@ -16,6 +16,25 @@ LL + #[derive(Copy)]
LL | struct NotCopy; LL | struct NotCopy;
| |
error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
--> $DIR/wf-const-type.rs:10:12
|
LL | const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`, which is required by `Option<NotCopy>: Copy`
|
= note: required for `Option<NotCopy>` to implement `Copy`
note: required by a bound in `IsCopy`
--> $DIR/wf-const-type.rs:7:17
|
LL | struct IsCopy<T:Copy> { 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 error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
--> $DIR/wf-const-type.rs:10:50 --> $DIR/wf-const-type.rs:10:50
| |
@ -34,6 +53,6 @@ LL + #[derive(Copy)]
LL | struct NotCopy; 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`. For more information about this error, try `rustc --explain E0277`.

View File

@ -10,6 +10,7 @@ struct NotCopy;
static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None }; static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
//~^ ERROR E0277 //~^ ERROR E0277
//~| ERROR E0277 //~| ERROR E0277
//~| ERROR E0277
fn main() { } fn main() { }

View File

@ -16,6 +16,25 @@ LL + #[derive(Copy)]
LL | struct NotCopy; LL | struct NotCopy;
| |
error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
--> $DIR/wf-static-type.rs:10:13
|
LL | static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `NotCopy`, which is required by `Option<NotCopy>: Copy`
|
= note: required for `Option<NotCopy>` to implement `Copy`
note: required by a bound in `IsCopy`
--> $DIR/wf-static-type.rs:7:17
|
LL | struct IsCopy<T:Copy> { 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 error[E0277]: the trait bound `NotCopy: Copy` is not satisfied
--> $DIR/wf-static-type.rs:10:51 --> $DIR/wf-static-type.rs:10:51
| |
@ -34,6 +53,6 @@ LL + #[derive(Copy)]
LL | struct NotCopy; 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`. For more information about this error, try `rustc --explain E0277`.