Rollup merge of #61698 - davidtwco:ice-const-generic-length, r=varkor
typeck: Fix const generic in repeat param ICE. Fixes #61336. Turns out this wasn't related to #49147 after all. r? @varkor
This commit is contained in:
commit
bd57c187fb
6 changed files with 104 additions and 25 deletions
|
|
@ -2155,6 +2155,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
|||
result_ty
|
||||
}
|
||||
|
||||
/// Returns the `DefId` of the constant parameter that the provided expression is a path to.
|
||||
pub fn const_param_def_id(&self, expr: &hir::Expr) -> Option<DefId> {
|
||||
match &expr.node {
|
||||
ExprKind::Path(hir::QPath::Resolved(_, path)) => match path.res {
|
||||
Res::Def(DefKind::ConstParam, did) => Some(did),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ast_const_to_const(
|
||||
&self,
|
||||
ast_const: &hir::AnonConst,
|
||||
|
|
@ -2185,19 +2196,17 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o {
|
|||
}
|
||||
}
|
||||
|
||||
if let ExprKind::Path(ref qpath) = expr.node {
|
||||
if let hir::QPath::Resolved(_, ref path) = qpath {
|
||||
if let Res::Def(DefKind::ConstParam, def_id) = path.res {
|
||||
let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
|
||||
let item_id = tcx.hir().get_parent_node(node_id);
|
||||
let item_def_id = tcx.hir().local_def_id(item_id);
|
||||
let generics = tcx.generics_of(item_def_id);
|
||||
let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
|
||||
let name = tcx.hir().name(node_id).as_interned_str();
|
||||
const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
|
||||
}
|
||||
}
|
||||
};
|
||||
if let Some(def_id) = self.const_param_def_id(expr) {
|
||||
// Find the name and index of the const parameter by indexing the generics of the
|
||||
// parent item and construct a `ParamConst`.
|
||||
let node_id = tcx.hir().as_local_node_id(def_id).unwrap();
|
||||
let item_id = tcx.hir().get_parent_node(node_id);
|
||||
let item_def_id = tcx.hir().local_def_id(item_id);
|
||||
let generics = tcx.generics_of(item_def_id);
|
||||
let index = generics.param_def_id_to_index[&tcx.hir().local_def_id(node_id)];
|
||||
let name = tcx.hir().name(node_id).as_interned_str();
|
||||
const_.val = ConstValue::Param(ty::ParamConst::new(index, name));
|
||||
}
|
||||
|
||||
tcx.mk_const(const_)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2504,6 +2504,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
ty
|
||||
}
|
||||
|
||||
/// Returns the `DefId` of the constant parameter that the provided expression is a path to.
|
||||
pub fn const_param_def_id(&self, hir_c: &hir::AnonConst) -> Option<DefId> {
|
||||
AstConv::const_param_def_id(self, &self.tcx.hir().body(hir_c.body).value)
|
||||
}
|
||||
|
||||
pub fn to_const(&self, ast_c: &hir::AnonConst, ty: Ty<'tcx>) -> &'tcx ty::Const<'tcx> {
|
||||
AstConv::ast_const_to_const(self, ast_c, ty)
|
||||
}
|
||||
|
|
@ -4479,19 +4484,24 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
ExprKind::Repeat(ref element, ref count) => {
|
||||
let count_def_id = tcx.hir().local_def_id_from_hir_id(count.hir_id);
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id);
|
||||
let instance = ty::Instance::resolve(
|
||||
tcx.global_tcx(),
|
||||
param_env,
|
||||
count_def_id,
|
||||
substs,
|
||||
).unwrap();
|
||||
let global_id = GlobalId {
|
||||
instance,
|
||||
promoted: None
|
||||
let count = if self.const_param_def_id(count).is_some() {
|
||||
Ok(self.to_const(count, self.tcx.type_of(count_def_id)))
|
||||
} else {
|
||||
let param_env = ty::ParamEnv::empty();
|
||||
let substs = InternalSubsts::identity_for_item(tcx.global_tcx(), count_def_id);
|
||||
let instance = ty::Instance::resolve(
|
||||
tcx.global_tcx(),
|
||||
param_env,
|
||||
count_def_id,
|
||||
substs,
|
||||
).unwrap();
|
||||
let global_id = GlobalId {
|
||||
instance,
|
||||
promoted: None
|
||||
};
|
||||
|
||||
tcx.const_eval(param_env.and(global_id))
|
||||
};
|
||||
let count = tcx.const_eval(param_env.and(global_id));
|
||||
|
||||
let uty = match expected {
|
||||
ExpectHasType(uty) => {
|
||||
|
|
|
|||
12
src/test/ui/const-generics/issue-61336-1.rs
Normal file
12
src/test/ui/const-generics/issue-61336-1.rs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
|
||||
[x; N]
|
||||
//~^ ERROR array lengths can't depend on generic parameters
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: [u32; 5] = f::<u32, 5>(3);
|
||||
assert_eq!(x, [3u32; 5]);
|
||||
}
|
||||
14
src/test/ui/const-generics/issue-61336-1.stderr
Normal file
14
src/test/ui/const-generics/issue-61336-1.stderr
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/issue-61336-1.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: array lengths can't depend on generic parameters
|
||||
--> $DIR/issue-61336-1.rs:5:9
|
||||
|
|
||||
LL | [x; N]
|
||||
| ^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
16
src/test/ui/const-generics/issue-61336.rs
Normal file
16
src/test/ui/const-generics/issue-61336.rs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
fn f<T: Copy, const N: usize>(x: T) -> [T; N] {
|
||||
[x; N]
|
||||
}
|
||||
|
||||
fn g<T, const N: usize>(x: T) -> [T; N] {
|
||||
[x; N]
|
||||
//~^ ERROR the trait bound `T: std::marker::Copy` is not satisfied [E0277]
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x: [u32; 5] = f::<u32, 5>(3);
|
||||
assert_eq!(x, [3u32; 5]);
|
||||
}
|
||||
18
src/test/ui/const-generics/issue-61336.stderr
Normal file
18
src/test/ui/const-generics/issue-61336.stderr
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/issue-61336.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `T: std::marker::Copy` is not satisfied
|
||||
--> $DIR/issue-61336.rs:9:5
|
||||
|
|
||||
LL | [x; N]
|
||||
| ^^^^^^ the trait `std::marker::Copy` is not implemented for `T`
|
||||
|
|
||||
= help: consider adding a `where T: std::marker::Copy` bound
|
||||
= note: the `Copy` trait is required because the repeated element will be copied
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue