mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
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:
parent
a09d91b04a
commit
ace436743f
@ -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).
|
||||
|
@ -25,7 +25,7 @@ impl<T: Copy> DataHolder<T> {
|
||||
}
|
||||
|
||||
<IsCopy<T>>::VALUE
|
||||
} as usize] = [];
|
||||
} as usize] = []; //~ ERROR unconstrained generic constant
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -29,5 +29,30 @@ LL | | } as usize] = [];
|
||||
<IsCopy<T>>::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;
|
||||
}
|
||||
|
||||
<IsCopy<T>>::VALUE
|
||||
} as usize]:`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -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
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
@ -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`.
|
@ -8,6 +8,7 @@ struct Foo<T:Trait> {
|
||||
|
||||
static X: Foo<usize> = Foo {
|
||||
//~^ ERROR E0277
|
||||
//~| ERROR E0277
|
||||
x: 1, //~ ERROR: E0277
|
||||
};
|
||||
|
||||
|
@ -16,7 +16,25 @@ LL | struct Foo<T:Trait> {
|
||||
| ^^^^^ 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<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,
|
||||
| ^ the trait `Trait` is not implemented for `usize`
|
||||
@ -32,6 +50,6 @@ note: required by a bound in `Foo`
|
||||
LL | struct Foo<T:Trait> {
|
||||
| ^^^^^ 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`.
|
||||
|
@ -10,6 +10,7 @@ struct NotCopy;
|
||||
const FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
|
||||
//~^ ERROR E0277
|
||||
//~| ERROR E0277
|
||||
//~| ERROR E0277
|
||||
|
||||
|
||||
fn main() { }
|
||||
|
@ -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<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
|
||||
--> $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`.
|
||||
|
@ -10,6 +10,7 @@ struct NotCopy;
|
||||
static FOO: IsCopy<Option<NotCopy>> = IsCopy { t: None };
|
||||
//~^ ERROR E0277
|
||||
//~| ERROR E0277
|
||||
//~| ERROR E0277
|
||||
|
||||
|
||||
fn main() { }
|
||||
|
@ -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<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
|
||||
--> $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`.
|
||||
|
Loading…
Reference in New Issue
Block a user