mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 11:48:30 +00:00
Check type of const param correctly in MIR typeck
This commit is contained in:
parent
cbfdf0b014
commit
0160c60c78
@ -1773,6 +1773,22 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
||||
{
|
||||
span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
|
||||
}
|
||||
} else if let Const::Ty(_, ct) = constant.const_
|
||||
&& let ty::ConstKind::Param(p) = ct.kind()
|
||||
{
|
||||
let body_def_id = self.universal_regions.defining_ty.def_id();
|
||||
let const_param = tcx.generics_of(body_def_id).const_param(p, tcx);
|
||||
self.ascribe_user_type(
|
||||
constant.const_.ty(),
|
||||
ty::UserType::new(ty::UserTypeKind::TypeOf(
|
||||
const_param.def_id,
|
||||
UserArgs {
|
||||
args: self.universal_regions.defining_ty.args(),
|
||||
user_self_ty: None,
|
||||
},
|
||||
)),
|
||||
locations.span(self.body),
|
||||
);
|
||||
}
|
||||
|
||||
if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() {
|
||||
|
@ -184,6 +184,20 @@ impl<'tcx> DefiningTy<'tcx> {
|
||||
| DefiningTy::GlobalAsm(def_id) => def_id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the args of the `DefiningTy`. These are equivalent to the identity
|
||||
/// substs of the body, but replaced with region vids.
|
||||
pub(crate) fn args(&self) -> ty::GenericArgsRef<'tcx> {
|
||||
match *self {
|
||||
DefiningTy::Closure(_, args)
|
||||
| DefiningTy::Coroutine(_, args)
|
||||
| DefiningTy::CoroutineClosure(_, args)
|
||||
| DefiningTy::FnDef(_, args)
|
||||
| DefiningTy::Const(_, args)
|
||||
| DefiningTy::InlineConst(_, args) => args,
|
||||
DefiningTy::GlobalAsm(_) => ty::List::empty(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -0,0 +1,16 @@
|
||||
// Ensure that we actually treat `N`'s type as `Invariant<'static>` in MIR typeck.
|
||||
|
||||
#![feature(adt_const_params)]
|
||||
|
||||
use std::marker::ConstParamTy;
|
||||
use std::ops::Deref;
|
||||
|
||||
#[derive(ConstParamTy, PartialEq, Eq)]
|
||||
struct Invariant<'a>(<&'a () as Deref>::Target);
|
||||
|
||||
fn test<'a, const N: Invariant<'static>>() {
|
||||
let x: Invariant<'a> = N;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,14 @@
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/check-type-in-mir.rs:12:28
|
||||
|
|
||||
LL | fn test<'a, const N: Invariant<'static>>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let x: Invariant<'a> = N;
|
||||
| ^ assignment requires that `'a` must outlive `'static`
|
||||
|
|
||||
= note: requirement occurs because of the type `Invariant<'_>`, which makes the generic argument `'_` invariant
|
||||
= note: the struct `Invariant<'a>` is invariant over the parameter `'a`
|
||||
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -0,0 +1,12 @@
|
||||
// Ensure that we actually treat `N`'s type as `&'a u32` in MIR typeck.
|
||||
|
||||
#![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
|
||||
//~^ WARN the feature `unsized_const_params` is incomplete
|
||||
//~| WARN the feature `generic_const_parameter_types` is incomplete
|
||||
|
||||
fn foo<'a, const N: &'a u32>() {
|
||||
let b: &'static u32 = N;
|
||||
//~^ ERROR lifetime may not live long enough
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,27 @@
|
||||
warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/check-type-in-mir.rs:3:12
|
||||
|
|
||||
LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes
|
||||
--> $DIR/check-type-in-mir.rs:3:52
|
||||
|
|
||||
LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information
|
||||
|
||||
error: lifetime may not live long enough
|
||||
--> $DIR/check-type-in-mir.rs:8:12
|
||||
|
|
||||
LL | fn foo<'a, const N: &'a u32>() {
|
||||
| -- lifetime `'a` defined here
|
||||
LL | let b: &'static u32 = N;
|
||||
| ^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
|
||||
|
||||
error: aborting due to 1 previous error; 2 warnings emitted
|
||||
|
Loading…
Reference in New Issue
Block a user