diff options
| author | kennytm <kennytm@gmail.com> | 2019-03-24 15:32:54 +0800 |
|---|---|---|
| committer | kennytm <kennytm@gmail.com> | 2019-03-24 19:00:18 +0800 |
| commit | 70cf3255023ec3034256def20f5d7cda0a1e663d (patch) | |
| tree | 880d422fe6867d6cf9598458d5f18de27e2ceb43 /src | |
| parent | cb2dde63d5cdcee619ad65de79029629ccee7604 (diff) | |
| parent | 5032643538da3e121a940438623adf820f95ae64 (diff) | |
Rollup merge of #59355 - varkor:const-param-struct-ice, r=petrochenkov
Fix ICE with const generic param in struct Fixes https://github.com/rust-lang/rust/issues/59340. r? @petrochenkov
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_resolve/lib.rs | 25 | ||||
| -rw-r--r-- | src/test/ui/const-generics/struct-with-invalid-const-param.rs | 6 | ||||
| -rw-r--r-- | src/test/ui/const-generics/struct-with-invalid-const-param.stderr | 15 |
3 files changed, 37 insertions, 9 deletions
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 38ca5f0b664..5a123e8b1a6 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -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 that are 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,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( diff --git a/src/test/ui/const-generics/struct-with-invalid-const-param.rs b/src/test/ui/const-generics/struct-with-invalid-const-param.rs new file mode 100644 index 00000000000..207b07bf695 --- /dev/null +++ b/src/test/ui/const-generics/struct-with-invalid-const-param.rs @@ -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() {} diff --git a/src/test/ui/const-generics/struct-with-invalid-const-param.stderr b/src/test/ui/const-generics/struct-with-invalid-const-param.stderr new file mode 100644 index 00000000000..561464b21cc --- /dev/null +++ b/src/test/ui/const-generics/struct-with-invalid-const-param.stderr @@ -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`. |
