mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-06 20:28:33 +00:00
Fix ICE with const generic param in struct
This commit is contained in:
parent
7a4df3b53d
commit
f94f85bebd
@ -814,7 +814,7 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
|
|||||||
debug!("(resolving function) entering function");
|
debug!("(resolving function) entering function");
|
||||||
let (rib_kind, asyncness) = match function_kind {
|
let (rib_kind, asyncness) = match function_kind {
|
||||||
FnKind::ItemFn(_, ref header, ..) =>
|
FnKind::ItemFn(_, ref header, ..) =>
|
||||||
(ItemRibKind, header.asyncness.node),
|
(FnItemRibKind, header.asyncness.node),
|
||||||
FnKind::Method(_, ref sig, _, _) =>
|
FnKind::Method(_, ref sig, _, _) =>
|
||||||
(TraitOrImplItemRibKind, sig.header.asyncness.node),
|
(TraitOrImplItemRibKind, sig.header.asyncness.node),
|
||||||
FnKind::Closure(_) =>
|
FnKind::Closure(_) =>
|
||||||
@ -950,6 +950,10 @@ enum RibKind<'a> {
|
|||||||
/// upvars).
|
/// upvars).
|
||||||
TraitOrImplItemRibKind,
|
TraitOrImplItemRibKind,
|
||||||
|
|
||||||
|
/// We passed through a function definition. Disallow upvars.
|
||||||
|
/// Permit only those const parameters specified in the function's generics.
|
||||||
|
FnItemRibKind,
|
||||||
|
|
||||||
/// We passed through an item scope. Disallow upvars.
|
/// We passed through an item scope. Disallow upvars.
|
||||||
ItemRibKind,
|
ItemRibKind,
|
||||||
|
|
||||||
@ -3863,7 +3867,7 @@ impl<'a> Resolver<'a> {
|
|||||||
seen.insert(node_id, depth);
|
seen.insert(node_id, depth);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemRibKind | TraitOrImplItemRibKind => {
|
ItemRibKind | FnItemRibKind | TraitOrImplItemRibKind => {
|
||||||
// This was an attempt to access an upvar inside a
|
// This was an attempt to access an upvar inside a
|
||||||
// named function item. This is not allowed, so we
|
// named function item. This is not allowed, so we
|
||||||
// report an error.
|
// report an error.
|
||||||
@ -3897,7 +3901,7 @@ impl<'a> Resolver<'a> {
|
|||||||
ConstantItemRibKind => {
|
ConstantItemRibKind => {
|
||||||
// Nothing to do. Continue.
|
// Nothing to do. Continue.
|
||||||
}
|
}
|
||||||
ItemRibKind => {
|
ItemRibKind | FnItemRibKind => {
|
||||||
// This was an attempt to use a type parameter outside its scope.
|
// This was an attempt to use a type parameter outside its scope.
|
||||||
if record_used {
|
if record_used {
|
||||||
resolve_error(
|
resolve_error(
|
||||||
@ -3912,21 +3916,27 @@ impl<'a> Resolver<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Def::ConstParam(..) => {
|
Def::ConstParam(..) => {
|
||||||
// A const param is always declared in a signature, which is always followed by
|
let mut ribs = ribs.iter().peekable();
|
||||||
// some kind of function rib kind (specifically, ItemRibKind in the case of a
|
if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
|
||||||
// normal function), so we can skip the first rib as it will be guaranteed to
|
// When declaring const parameters inside function signatures, the first rib
|
||||||
// (spuriously) conflict with the const param.
|
// is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
|
||||||
for rib in &ribs[1..] {
|
// (spuriously) conflicting with the const param.
|
||||||
if let ItemRibKind = rib.kind {
|
ribs.next();
|
||||||
// This was an attempt to use a const parameter outside its scope.
|
}
|
||||||
if record_used {
|
for rib in ribs {
|
||||||
resolve_error(
|
match rib.kind {
|
||||||
self,
|
ItemRibKind | FnItemRibKind => {
|
||||||
span,
|
// This was an attempt to use a const parameter outside its scope.
|
||||||
ResolutionError::GenericParamsFromOuterFunction(def),
|
if record_used {
|
||||||
);
|
resolve_error(
|
||||||
|
self,
|
||||||
|
span,
|
||||||
|
ResolutionError::GenericParamsFromOuterFunction(def),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return Def::Err;
|
||||||
}
|
}
|
||||||
return Def::Err;
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,6 @@
|
|||||||
|
#![feature(const_generics)]
|
||||||
|
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
|
||||||
|
struct S<const C: u8>(C); //~ ERROR expected type, found const parameter
|
||||||
|
|
||||||
|
fn main() {}
|
@ -0,0 +1,15 @@
|
|||||||
|
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||||
|
--> $DIR/struct-with-invalid-const-param.rs:1:12
|
||||||
|
|
|
||||||
|
LL | #![feature(const_generics)]
|
||||||
|
| ^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error[E0573]: expected type, found const parameter `C`
|
||||||
|
--> $DIR/struct-with-invalid-const-param.rs:4:23
|
||||||
|
|
|
||||||
|
LL | struct S<const C: u8>(C);
|
||||||
|
| ^ help: a struct with a similar name exists: `S`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0573`.
|
Loading…
Reference in New Issue
Block a user