From 7956b1cef71ef633fb0e5e55451c5bb9ee9c59e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 10 Aug 2020 13:26:16 -0700 Subject: [PATCH] Assoc `const`s don't have generics Fix #74264. --- src/librustc_resolve/late/diagnostics.rs | 11 ++++++++++- src/librustc_resolve/late/lifetimes.rs | 6 ++++-- .../missing-lifetime-in-assoc-const-type.rs | 5 +++++ .../missing-lifetime-in-assoc-const-type.stderr | 15 +++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) create mode 100644 src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.rs create mode 100644 src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.stderr diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs index c9e83864a938..e9c463c7a3ef 100644 --- a/src/librustc_resolve/late/diagnostics.rs +++ b/src/librustc_resolve/late/diagnostics.rs @@ -17,7 +17,7 @@ use rustc_hir::PrimTy; use rustc_session::config::nightly_options; use rustc_span::hygiene::MacroKind; use rustc_span::symbol::{kw, sym, Ident}; -use rustc_span::{BytePos, Span}; +use rustc_span::{BytePos, Span, DUMMY_SP}; use log::debug; @@ -1273,6 +1273,15 @@ impl<'tcx> LifetimeContext<'_, 'tcx> { let should_break; introduce_suggestion.push(match missing { MissingLifetimeSpot::Generics(generics) => { + if generics.span == DUMMY_SP { + // Account for malformed generics in the HIR. This shouldn't happen, + // but if we make a mistake elsewhere, mainly by keeping something in + // `missing_named_lifetime_spots` that we shouldn't, like associated + // `const`s or making a mistake in the AST lowering we would provide + // non-sensical suggestions. Guard against that by skipping these. + // (#74264) + continue; + } msg = "consider introducing a named lifetime parameter".to_string(); should_break = true; if let Some(param) = generics.params.iter().find(|p| match p.kind { diff --git a/src/librustc_resolve/late/lifetimes.rs b/src/librustc_resolve/late/lifetimes.rs index 0b881b089dea..6cb928437662 100644 --- a/src/librustc_resolve/late/lifetimes.rs +++ b/src/librustc_resolve/late/lifetimes.rs @@ -711,9 +711,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>) { use self::hir::TraitItemKind::*; - self.missing_named_lifetime_spots.push((&trait_item.generics).into()); match trait_item.kind { Fn(ref sig, _) => { + self.missing_named_lifetime_spots.push((&trait_item.generics).into()); let tcx = self.tcx; self.visit_early_late( Some(tcx.hir().get_parent_item(trait_item.hir_id)), @@ -721,8 +721,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { &trait_item.generics, |this| intravisit::walk_trait_item(this, trait_item), ); + self.missing_named_lifetime_spots.pop(); } Type(bounds, ref ty) => { + self.missing_named_lifetime_spots.push((&trait_item.generics).into()); let generics = &trait_item.generics; let mut index = self.next_early_index(); debug!("visit_ty: index = {}", index); @@ -757,6 +759,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { this.visit_ty(ty); } }); + self.missing_named_lifetime_spots.pop(); } Const(_, _) => { // Only methods and types support generics. @@ -764,7 +767,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { intravisit::walk_trait_item(self, trait_item); } } - self.missing_named_lifetime_spots.pop(); } fn visit_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>) { diff --git a/src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.rs b/src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.rs new file mode 100644 index 000000000000..b9e0108fe714 --- /dev/null +++ b/src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.rs @@ -0,0 +1,5 @@ +trait ZstAssert: Sized { + const TYPE_NAME: &str = ""; //~ ERROR missing lifetime specifier +} + +fn main() {} diff --git a/src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.stderr b/src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.stderr new file mode 100644 index 000000000000..ee9d1a15d2a7 --- /dev/null +++ b/src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.stderr @@ -0,0 +1,15 @@ +error[E0106]: missing lifetime specifier + --> $DIR/missing-lifetime-in-assoc-const-type.rs:2:22 + | +LL | const TYPE_NAME: &str = ""; + | ^ expected named lifetime parameter + | +help: consider introducing a named lifetime parameter + | +LL | trait ZstAssert<'a>: Sized { +LL | const TYPE_NAME: &'a str = ""; + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0106`.