about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_resolve/src/late.rs50
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs106
2 files changed, 45 insertions, 111 deletions
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 533302a758f..efdedbebbea 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -12,10 +12,6 @@ use crate::{path_names_to_string, BindingError, Finalize, LexicalScopeBinding};
 use crate::{Module, ModuleOrUniformRoot, NameBinding, ParentScope, PathResult};
 use crate::{ResolutionError, Resolver, Segment, UseError};
 
-use diagnostics::{
-    original_label, original_lifetime, original_lifetime_param, shadower_label, shadower_lifetime,
-};
-
 use rustc_ast::ptr::P;
 use rustc_ast::visit::{self, AssocCtxt, BoundKind, FnCtxt, FnKind, Visitor};
 use rustc_ast::*;
@@ -1902,6 +1898,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         let mut function_value_rib = Rib::new(kind);
         let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
         let mut seen_bindings = FxHashMap::default();
+        // Store all seen lifetimes names, and whether they were created in the currently processed
+        // parameter set.
         let mut seen_lifetimes = FxHashMap::default();
 
         // We also can't shadow bindings from the parent item
@@ -1920,20 +1918,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
 
         // Forbid shadowing lifetime bindings
         for rib in self.lifetime_ribs.iter().rev() {
-            seen_lifetimes.extend(
-                rib.bindings.iter().map(|(ident, _)| (*ident, original_lifetime(ident.span))),
-            );
+            seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| (*ident, false)));
             if let LifetimeRibKind::Item = rib.kind {
                 break;
             }
         }
-        for rib in self.label_ribs.iter().rev() {
-            if rib.kind.is_label_barrier() {
-                break;
-            }
-            seen_lifetimes
-                .extend(rib.bindings.iter().map(|(ident, _)| (*ident, original_label(ident.span))));
-        }
 
         for param in params {
             let ident = param.ident.normalize_to_macros_2_0();
@@ -1942,16 +1931,17 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             if let GenericParamKind::Lifetime = param.kind {
                 match seen_lifetimes.entry(ident) {
                     Entry::Occupied(entry) => {
-                        let original = *entry.get();
-                        diagnostics::signal_shadowing_problem(
+                        let original = *entry.key();
+                        let orig_is_param = *entry.get();
+                        diagnostics::signal_lifetime_shadowing(
                             self.r.session,
-                            ident.name,
                             original,
-                            shadower_lifetime(param.ident.span),
-                        )
+                            param.ident,
+                            orig_is_param,
+                        );
                     }
                     Entry::Vacant(entry) => {
-                        entry.insert(original_lifetime_param(param.ident.span));
+                        entry.insert(true);
                     }
                 }
             } else {
@@ -3155,26 +3145,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                 self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
             }
 
-            // Forbid shadowing lifetime bindings
             let ident = label.ident.normalize_to_macro_rules();
-            for rib in self.lifetime_ribs.iter().rev() {
-                if let Some((orig_ident, _)) = rib.bindings.get_key_value(&ident) {
-                    diagnostics::signal_shadowing_problem(
-                        self.r.session,
-                        label.ident.name,
-                        original_lifetime(orig_ident.span),
-                        shadower_label(label.ident.span),
-                    )
-                }
-            }
             for rib in self.label_ribs.iter_mut().rev() {
-                if let Some((orig_ident, _)) = rib.bindings.get_key_value(&ident) {
-                    diagnostics::signal_shadowing_problem(
-                        self.r.session,
-                        label.ident.name,
-                        original_label(orig_ident.span),
-                        shadower_label(label.ident.span),
-                    )
+                if let Some((&orig_ident, _)) = rib.bindings.get_key_value(&ident) {
+                    diagnostics::signal_label_shadowing(self.r.session, orig_ident, label.ident)
                 }
                 if rib.kind.is_label_barrier() {
                     rib.bindings.insert(ident, id);
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index b77bcaad354..552102be92c 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -2037,84 +2037,44 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
     }
 }
 
-#[derive(Copy, Clone, PartialEq)]
-enum ShadowKind {
-    Label,
-    Lifetime,
-}
-#[derive(Copy, Clone)]
-pub struct Original {
-    kind: ShadowKind,
-    span: Span,
-    param: bool,
-}
-#[derive(Copy, Clone)]
-pub struct Shadower {
-    kind: ShadowKind,
-    span: Span,
-}
-
-pub fn original_label(span: Span) -> Original {
-    Original { kind: ShadowKind::Label, span, param: false }
-}
-pub fn shadower_label(span: Span) -> Shadower {
-    Shadower { kind: ShadowKind::Label, span }
-}
-pub fn original_lifetime(span: Span) -> Original {
-    Original { kind: ShadowKind::Lifetime, span, param: false }
-}
-pub fn original_lifetime_param(span: Span) -> Original {
-    Original { kind: ShadowKind::Lifetime, span, param: true }
-}
-pub fn shadower_lifetime(span: Span) -> Shadower {
-    Shadower { kind: ShadowKind::Lifetime, span }
-}
-
-impl ShadowKind {
-    fn desc(&self) -> &'static str {
-        match *self {
-            ShadowKind::Label => "label",
-            ShadowKind::Lifetime => "lifetime",
-        }
-    }
-}
-
-pub fn signal_shadowing_problem(sess: &Session, name: Symbol, orig: Original, shadower: Shadower) {
-    let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
-        // lifetime/lifetime shadowing is an error
-        if orig.param {
-            struct_span_err!(
-                sess,
-                shadower.span,
-                E0263,
-                "lifetime name `{}` declared twice in the same scope",
-                name,
-            )
-        } else {
-            struct_span_err!(
-                sess,
-                shadower.span,
-                E0496,
-                "lifetime name `{}` shadows a lifetime name that is already in scope",
-                name,
-            )
-        }
-        .forget_guarantee()
+/// Report lifetime/lifetime shadowing as an error.
+pub fn signal_lifetime_shadowing(
+    sess: &Session,
+    orig: Ident,
+    shadower: Ident,
+    orig_is_param: bool,
+) {
+    let mut err = if orig_is_param {
+        struct_span_err!(
+            sess,
+            shadower.span,
+            E0263,
+            "lifetime name `{}` declared twice in the same scope",
+            orig.name,
+        )
     } else {
-        // shadowing involving a label is only a warning, due to issues with
-        // labels and lifetimes not being macro-hygienic.
-        sess.struct_span_warn(
+        struct_span_err!(
+            sess,
             shadower.span,
-            &format!(
-                "{} name `{}` shadows a {} name that is already in scope",
-                shadower.kind.desc(),
-                name,
-                orig.kind.desc()
-            ),
+            E0496,
+            "lifetime name `{}` shadows a lifetime name that is already in scope",
+            orig.name,
         )
     };
     err.span_label(orig.span, "first declared here");
-    err.span_label(shadower.span, format!("{} `{}` already in scope", orig.kind.desc(), name));
+    err.span_label(shadower.span, format!("lifetime `{}` already in scope", orig.name));
+    err.emit();
+}
+
+/// Shadowing involving a label is only a warning, due to issues with
+/// labels and lifetimes not being macro-hygienic.
+pub fn signal_label_shadowing(sess: &Session, orig: Ident, shadower: Ident) {
+    let mut err = sess.struct_span_warn(
+        shadower.span,
+        &format!("label name `{}` shadows a label name that is already in scope", orig.name),
+    );
+    err.span_label(orig.span, "first declared here");
+    err.span_label(shadower.span, format!("label `{}` already in scope", orig.name));
     err.emit();
 }