Skip to content

Commit 9926d69

Browse files
Check type of const param correctly in MIR typeck
1 parent 3ea711f commit 9926d69

File tree

4 files changed

+66
-0
lines changed

4 files changed

+66
-0
lines changed

compiler/rustc_borrowck/src/type_check/mod.rs

+16
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,22 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
421421
) {
422422
span_mirbug!(self, constant, "bad static type {:?} ({:?})", constant, terr);
423423
}
424+
} else if let Const::Ty(_, ct) = constant.const_
425+
&& let ty::ConstKind::Param(p) = ct.kind()
426+
{
427+
let body_def_id = self.typeck.universal_regions.defining_ty.def_id();
428+
let const_param = tcx.generics_of(body_def_id).const_param(p, tcx);
429+
self.typeck.ascribe_user_type(
430+
constant.const_.ty(),
431+
ty::UserType::new(ty::UserTypeKind::TypeOf(
432+
const_param.def_id,
433+
UserArgs {
434+
args: self.typeck.universal_regions.defining_ty.args(),
435+
user_self_ty: None,
436+
},
437+
)),
438+
locations.span(self.typeck.body),
439+
);
424440
}
425441

426442
if let ty::FnDef(def_id, args) = *constant.const_.ty().kind() {

compiler/rustc_borrowck/src/universal_regions.rs

+14
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,20 @@ impl<'tcx> DefiningTy<'tcx> {
184184
| DefiningTy::GlobalAsm(def_id) => def_id,
185185
}
186186
}
187+
188+
/// Returns the args of the `DefiningTy`. These are equivalent to the identity
189+
/// substs of the body, but replaced with region vids.
190+
pub(crate) fn args(&self) -> ty::GenericArgsRef<'tcx> {
191+
match *self {
192+
DefiningTy::Closure(_, args)
193+
| DefiningTy::Coroutine(_, args)
194+
| DefiningTy::CoroutineClosure(_, args)
195+
| DefiningTy::FnDef(_, args)
196+
| DefiningTy::Const(_, args)
197+
| DefiningTy::InlineConst(_, args) => args,
198+
DefiningTy::GlobalAsm(_) => ty::List::empty(),
199+
}
200+
}
187201
}
188202

189203
#[derive(Debug)]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Ensure that we actually treat `N`'s type as `&'a u32` in MIR typeck.
2+
3+
#![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
4+
5+
fn foo<'a, const N: &'a u32>() {
6+
let b: &'static u32 = N;
7+
}
8+
9+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
warning: the feature `unsized_const_params` is incomplete and may not be safe to use and/or cause compiler crashes
2+
--> $DIR/check-type.rs:3:12
3+
|
4+
LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
5+
| ^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #95174 <https://github.com/rust-lang/rust/issues/95174> for more information
8+
= note: `#[warn(incomplete_features)]` on by default
9+
10+
warning: the feature `generic_const_parameter_types` is incomplete and may not be safe to use and/or cause compiler crashes
11+
--> $DIR/check-type.rs:3:52
12+
|
13+
LL | #![feature(unsized_const_params, adt_const_params, generic_const_parameter_types)]
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
15+
|
16+
= note: see issue #137626 <https://github.com/rust-lang/rust/issues/137626> for more information
17+
18+
error: lifetime may not live long enough
19+
--> $DIR/check-type.rs:6:12
20+
|
21+
LL | fn foo<'a, const N: &'a u32>() {
22+
| -- lifetime `'a` defined here
23+
LL | let b: &'static u32 = N;
24+
| ^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
25+
26+
error: aborting due to 1 previous error; 2 warnings emitted
27+

0 commit comments

Comments
 (0)