Skip to content

Commit

Permalink
Rollup merge of #59355 - varkor:const-param-struct-ice, r=petrochenkov
Browse files Browse the repository at this point in the history
Fix ICE with const generic param in struct

Fixes #59340.

r? @petrochenkov
  • Loading branch information
kennytm committed Mar 24, 2019
2 parents cb2dde6 + 5032643 commit 70cf325
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 9 deletions.
25 changes: 16 additions & 9 deletions src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(_) =>
Expand Down Expand Up @@ -950,6 +950,10 @@ enum RibKind<'a> {
/// upvars).
TraitOrImplItemRibKind,

/// We passed through a function definition. Disallow upvars.
/// Permit only those const parameters that are specified in the function's generics.
FnItemRibKind,

/// We passed through an item scope. Disallow upvars.
ItemRibKind,

Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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(
Expand All @@ -3912,12 +3916,15 @@ 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 {
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 {
if let ItemRibKind | FnItemRibKind = rib.kind {
// This was an attempt to use a const parameter outside its scope.
if record_used {
resolve_error(
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/const-generics/struct-with-invalid-const-param.rs
Original file line number Diff line number Diff line change
@@ -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() {}
15 changes: 15 additions & 0 deletions src/test/ui/const-generics/struct-with-invalid-const-param.stderr
Original file line number Diff line number Diff line change
@@ -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`.

0 comments on commit 70cf325

Please sign in to comment.