Skip to content

Commit f102e38

Browse files
committed
Auto merge of rust-lang#138283 - compiler-errors:enforce-const-param, r=<try>
Enforce type of const param correctly in MIR typeck Properly intercepts and then annotates the type for a `ConstKind::Param` in the MIR. This code should probably be cleaned up, it's kinda spaghetti, but no better structure really occurred to me when writing this case. We could probably gate this behind the feature gate or add a fast path when the args have no free regions if perf is bad. r? `@BoxyUwU`
2 parents 385970f + c745d61 commit f102e38

File tree

3 files changed

+39
-0
lines changed

3 files changed

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

0 commit comments

Comments
 (0)