about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-08-10 13:26:16 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-08-11 11:06:21 -0700
commit7956b1cef71ef633fb0e5e55451c5bb9ee9c59e2 (patch)
tree8e0ba4163d57b08700bfbf9d8e6c6003734e214f
parent0f7205f2020ff5acefac83e354acea4c69f2ea0e (diff)
downloadrust-7956b1cef71ef633fb0e5e55451c5bb9ee9c59e2.tar.gz
rust-7956b1cef71ef633fb0e5e55451c5bb9ee9c59e2.zip
Assoc `const`s don't have generics
Fix #74264.
-rw-r--r--src/librustc_resolve/late/diagnostics.rs11
-rw-r--r--src/librustc_resolve/late/lifetimes.rs6
-rw-r--r--src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.rs5
-rw-r--r--src/test/ui/suggestions/missing-lifetime-in-assoc-const-type.stderr15
4 files changed, 34 insertions, 3 deletions
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index c9e83864a93..e9c463c7a3e 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 0b881b089de..6cb92843766 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 00000000000..b9e0108fe71
--- /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 00000000000..ee9d1a15d2a
--- /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`.