mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-24 07:44:10 +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");
|
||||
let (rib_kind, asyncness) = match function_kind {
|
||||
FnKind::ItemFn(_, ref header, ..) =>
|
||||
(ItemRibKind, header.asyncness.node),
|
||||
(FnItemRibKind, header.asyncness.node),
|
||||
FnKind::Method(_, ref sig, _, _) =>
|
||||
(TraitOrImplItemRibKind, sig.header.asyncness.node),
|
||||
FnKind::Closure(_) =>
|
||||
@ -950,6 +950,10 @@ enum RibKind<'a> {
|
||||
/// upvars).
|
||||
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.
|
||||
ItemRibKind,
|
||||
|
||||
@ -3863,7 +3867,7 @@ impl<'a> Resolver<'a> {
|
||||
seen.insert(node_id, depth);
|
||||
}
|
||||
}
|
||||
ItemRibKind | TraitOrImplItemRibKind => {
|
||||
ItemRibKind | FnItemRibKind | TraitOrImplItemRibKind => {
|
||||
// This was an attempt to access an upvar inside a
|
||||
// named function item. This is not allowed, so we
|
||||
// report an error.
|
||||
@ -3897,7 +3901,7 @@ impl<'a> Resolver<'a> {
|
||||
ConstantItemRibKind => {
|
||||
// Nothing to do. Continue.
|
||||
}
|
||||
ItemRibKind => {
|
||||
ItemRibKind | FnItemRibKind => {
|
||||
// This was an attempt to use a type parameter outside its scope.
|
||||
if record_used {
|
||||
resolve_error(
|
||||
@ -3912,21 +3916,27 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
Def::ConstParam(..) => {
|
||||
// A const param is always declared in a signature, which is always followed by
|
||||
// some kind of function rib kind (specifically, ItemRibKind in the case of a
|
||||
// normal function), so we can skip the first rib as it will be guaranteed to
|
||||
// (spuriously) conflict with the const param.
|
||||
for rib in &ribs[1..] {
|
||||
if let ItemRibKind = rib.kind {
|
||||
// This was an attempt to use a const parameter outside its scope.
|
||||
if record_used {
|
||||
resolve_error(
|
||||
self,
|
||||
span,
|
||||
ResolutionError::GenericParamsFromOuterFunction(def),
|
||||
);
|
||||
let mut ribs = ribs.iter().peekable();
|
||||
if let Some(Rib { kind: FnItemRibKind, .. }) = ribs.peek() {
|
||||
// When declaring const parameters inside function signatures, the first rib
|
||||
// is always a `FnItemRibKind`. In this case, we can skip it, to avoid it
|
||||
// (spuriously) conflicting with the const param.
|
||||
ribs.next();
|
||||
}
|
||||
for rib in ribs {
|
||||
match rib.kind {
|
||||
ItemRibKind | FnItemRibKind => {
|
||||
// This was an attempt to use a const parameter outside its scope.
|
||||
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