From 6e1b0105c60cfca15930a6fdf8a3b07db528c749 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sat, 4 Dec 2021 21:20:58 +0100 Subject: [PATCH 1/9] Diagnose shadowing on AST. --- compiler/rustc_resolve/src/late.rs | 119 +++++-- .../rustc_resolve/src/late/diagnostics.rs | 82 +++++ compiler/rustc_resolve/src/late/lifetimes.rs | 333 ++---------------- 3 files changed, 209 insertions(+), 325 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 73d6566e3cd97..533302a758f17 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -12,6 +12,10 @@ 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::*; @@ -172,6 +176,23 @@ impl RibKind<'_> { AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true, } } + + /// This rib forbids referring to labels defined in upwards ribs. + fn is_label_barrier(self) -> bool { + match self { + NormalRibKind | MacroDefinition(..) => false, + + AssocItemRibKind + | ClosureOrAsyncRibKind + | FnItemRibKind + | ItemRibKind(..) + | ConstantItemRibKind(..) + | ModuleRibKind(..) + | ForwardGenericParamBanRibKind + | ConstParamTyRibKind + | InlineAsmSymRibKind => true, + } + } } /// A single local scope. @@ -732,7 +753,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> { // Create a value rib for the function. self.with_rib(ValueNS, rib_kind, |this| { // Create a label rib for the function. - this.with_label_rib(rib_kind, |this| { + this.with_label_rib(FnItemRibKind, |this| { let async_node_id = fn_kind.header().and_then(|h| h.asyncness.opt_return_id()); if let FnKind::Fn(_, _, _, _, generics, _) = fn_kind { @@ -1585,22 +1606,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { let ribs = &self.label_ribs[rib_index + 1..]; for rib in ribs { - match rib.kind { - NormalRibKind | MacroDefinition(..) => { - // Nothing to do. Continue. - } - - AssocItemRibKind - | ClosureOrAsyncRibKind - | FnItemRibKind - | ItemRibKind(..) - | ConstantItemRibKind(..) - | ModuleRibKind(..) - | ForwardGenericParamBanRibKind - | ConstParamTyRibKind - | InlineAsmSymRibKind => { - return false; - } + if rib.kind.is_label_barrier() { + return false; } } @@ -1895,6 +1902,7 @@ 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(); + let mut seen_lifetimes = FxHashMap::default(); // We also can't shadow bindings from the parent item if let AssocItemRibKind = kind { @@ -1910,20 +1918,52 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { add_bindings_for_ns(TypeNS); } + // 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))), + ); + 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(); debug!("with_generic_param_rib: {}", param.id); - match seen_bindings.entry(ident) { - Entry::Occupied(entry) => { - let span = *entry.get(); - let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); - if !matches!(param.kind, GenericParamKind::Lifetime) { - self.report_error(param.ident.span, err); + if let GenericParamKind::Lifetime = param.kind { + match seen_lifetimes.entry(ident) { + Entry::Occupied(entry) => { + let original = *entry.get(); + diagnostics::signal_shadowing_problem( + self.r.session, + ident.name, + original, + shadower_lifetime(param.ident.span), + ) + } + Entry::Vacant(entry) => { + entry.insert(original_lifetime_param(param.ident.span)); } } - Entry::Vacant(entry) => { - entry.insert(param.ident.span); + } else { + match seen_bindings.entry(ident) { + Entry::Occupied(entry) => { + let span = *entry.get(); + let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); + self.report_error(param.ident.span, err); + } + Entry::Vacant(entry) => { + entry.insert(param.ident.span); + } } } @@ -3114,8 +3154,35 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if label.ident.as_str().as_bytes()[1] != b'_' { 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 rib.kind.is_label_barrier() { + rib.bindings.insert(ident, id); + break; + } + } + self.with_label_rib(NormalRibKind, |this| { - let ident = label.ident.normalize_to_macro_rules(); this.label_ribs.last_mut().unwrap().bindings.insert(ident, id); f(this); }); diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index a6a04ac9ea6fc..b77bcaad3542e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -25,6 +25,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE}; use rustc_hir::PrimTy; use rustc_session::lint; use rustc_session::parse::feature_err; +use rustc_session::Session; use rustc_span::edition::Edition; use rustc_span::hygiene::MacroKind; use rustc_span::lev_distance::find_best_match_for_name; @@ -2036,6 +2037,87 @@ 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() + } else { + // shadowing involving a label is only a warning, due to issues with + // labels and lifetimes not being macro-hygienic. + sess.struct_span_warn( + shadower.span, + &format!( + "{} name `{}` shadows a {} name that is already in scope", + shadower.kind.desc(), + name, + orig.kind.desc() + ), + ) + }; + err.span_label(orig.span, "first declared here"); + err.span_label(shadower.span, format!("{} `{}` already in scope", orig.kind.desc(), name)); + err.emit(); +} + impl<'tcx> LifetimeContext<'_, 'tcx> { pub(crate) fn report_missing_lifetime_specifiers( &self, diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 2fe65441ac90e..59c2db25b8e05 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -23,7 +23,7 @@ use rustc_middle::middle::resolve_lifetime::*; use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use rustc_middle::{bug, span_bug}; use rustc_span::def_id::DefId; -use rustc_span::symbol::{kw, sym, Ident, Symbol}; +use rustc_span::symbol::{kw, sym, Ident}; use rustc_span::Span; use std::borrow::Cow; use std::cell::Cell; @@ -161,9 +161,6 @@ pub(crate) struct LifetimeContext<'a, 'tcx> { /// we eventually need lifetimes resolve for trait items. trait_definition_only: bool, - /// List of labels in the function/method currently under analysis. - labels_in_fn: Vec, - /// Cache for cross-crate per-definition object lifetime defaults. xcrate_object_lifetime_defaults: DefIdMap>, @@ -434,7 +431,6 @@ fn do_resolve( map: &mut named_region_map, scope: ROOT_SCOPE, trait_definition_only, - labels_in_fn: vec![], xcrate_object_lifetime_defaults: Default::default(), missing_named_lifetime_spots: vec![], }; @@ -641,14 +637,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } fn visit_nested_body(&mut self, body: hir::BodyId) { - // Each body has their own set of labels, save labels. - let saved = take(&mut self.labels_in_fn); let body = self.tcx.hir().body(body); - extract_labels(self, body); - self.with(Scope::Body { id: body.id(), s: self.scope }, |_, this| { + self.with(Scope::Body { id: body.id(), s: self.scope }, |this| { this.visit_body(body); }); - self.labels_in_fn = saved; } fn visit_fn( @@ -683,9 +675,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: true, }; - self.with(scope, move |_old_scope, this| { - intravisit::walk_fn(this, fk, fd, b, s, hir_id) - }); + self.with(scope, move |this| intravisit::walk_fn(this, fk, fd, b, s, hir_id)); } } } @@ -720,7 +710,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => { // No lifetime parameters, but implied 'static. let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE }; - self.with(scope, |_, this| intravisit::walk_item(this, item)); + self.with(scope, |this| intravisit::walk_item(this, item)); } hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => { // Opaque types are visited when we visit the @@ -807,10 +797,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { s: ROOT_SCOPE, allow_late_bound: false, }; - self.with(scope, |old_scope, this| { - this.check_lifetime_params(old_scope, &generics.params); + self.with(scope, |this| { let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |_, this| { + this.with(scope, |this| { intravisit::walk_item(this, item); }); }); @@ -873,10 +862,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: true, }; - self.with(scope, |old_scope, this| { + self.with(scope, |this| { // a bare fn has no bounds, so everything // contained within is scoped within its binder. - this.check_lifetime_params(old_scope, &c.generic_params); intravisit::walk_ty(this, ty); }); self.missing_named_lifetime_spots.pop(); @@ -884,7 +872,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { hir::TyKind::TraitObject(bounds, ref lifetime, _) => { debug!(?bounds, ?lifetime, "TraitObject"); let scope = Scope::TraitRefBoundary { s: self.scope }; - self.with(scope, |_, this| { + self.with(scope, |this| { for bound in bounds { this.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); } @@ -923,7 +911,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(), s: self.scope, }; - self.with(scope, |_, this| this.visit_ty(&mt.ty)); + self.with(scope, |this| this.visit_ty(&mt.ty)); } hir::TyKind::OpaqueDef(item_id, lifetimes) => { // Resolve the lifetimes in the bounds to the lifetime defs in the generics. @@ -944,9 +932,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { // Elided lifetimes are not allowed in non-return // position impl Trait let scope = Scope::TraitRefBoundary { s: self.scope }; - self.with(scope, |_, this| { + self.with(scope, |this| { let scope = Scope::Elision { elide: Elide::Forbid, s: this.scope }; - this.with(scope, |_, this| { + this.with(scope, |this| { intravisit::walk_item(this, opaque_ty); }) }); @@ -1052,7 +1040,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { if let Some(elision_region) = elision { let scope = Scope::Elision { elide: Elide::Exact(elision_region), s: self.scope }; - self.with(scope, |_old_scope, this| { + self.with(scope, |this| { let scope = Scope::Binder { hir_id: ty.hir_id, lifetimes, @@ -1062,10 +1050,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: false, }; - this.with(scope, |_old_scope, this| { + this.with(scope, |this| { this.visit_generics(generics); let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |_, this| { + this.with(scope, |this| { for bound in bounds { this.visit_param_bound(bound); } @@ -1082,9 +1070,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: false, }; - self.with(scope, |_old_scope, this| { + self.with(scope, |this| { let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |_, this| { + this.with(scope, |this| { this.visit_generics(generics); for bound in bounds { this.visit_param_bound(bound); @@ -1141,10 +1129,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: false, }; - self.with(scope, |old_scope, this| { - this.check_lifetime_params(old_scope, &generics.params); + self.with(scope, |this| { let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |_, this| { + this.with(scope, |this| { this.visit_generics(generics); for bound in bounds { this.visit_param_bound(bound); @@ -1210,10 +1197,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: true, }; - self.with(scope, |old_scope, this| { - this.check_lifetime_params(old_scope, &generics.params); + self.with(scope, |this| { let scope = Scope::TraitRefBoundary { s: this.scope }; - this.with(scope, |_, this| { + this.with(scope, |this| { this.visit_generics(generics); this.visit_ty(ty); }) @@ -1300,7 +1286,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) { let scope = Scope::TraitRefBoundary { s: self.scope }; - self.with(scope, |_, this| { + self.with(scope, |this| { for param in generics.params { match param.kind { GenericParamKind::Lifetime { .. } => {} @@ -1354,8 +1340,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: true, }; - this.with(scope, |old_scope, this| { - this.check_lifetime_params(old_scope, &bound_generic_params); + this.with(scope, |this| { this.visit_ty(&bounded_ty); walk_list!(this, visit_param_bound, bounds); }) @@ -1427,7 +1412,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type, allow_late_bound: true, }; - self.with(scope, |_, this| { + self.with(scope, |this| { intravisit::walk_param_bound(this, bound); }); } @@ -1479,8 +1464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { scope_type, allow_late_bound: true, }; - self.with(scope, |old_scope, this| { - this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params); + self.with(scope, |this| { walk_list!(this, visit_generic_param, trait_ref.bound_generic_params); this.visit_trait_ref(&trait_ref.trait_ref); }); @@ -1491,154 +1475,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { } } -#[derive(Copy, Clone, PartialEq)] -enum ShadowKind { - Label, - Lifetime, -} -struct Original { - kind: ShadowKind, - span: Span, -} -struct Shadower { - kind: ShadowKind, - span: Span, -} - -fn original_label(span: Span) -> Original { - Original { kind: ShadowKind::Label, span } -} -fn shadower_label(span: Span) -> Shadower { - Shadower { kind: ShadowKind::Label, span } -} -fn original_lifetime(span: Span) -> Original { - Original { kind: ShadowKind::Lifetime, span } -} -fn shadower_lifetime(param: &hir::GenericParam<'_>) -> Shadower { - Shadower { kind: ShadowKind::Lifetime, span: param.span } -} - -impl ShadowKind { - fn desc(&self) -> &'static str { - match *self { - ShadowKind::Label => "label", - ShadowKind::Lifetime => "lifetime", - } - } -} - -fn signal_shadowing_problem(tcx: TyCtxt<'_>, 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 - struct_span_err!( - tcx.sess, - shadower.span, - E0496, - "{} name `{}` shadows a \ - {} name that is already in scope", - shadower.kind.desc(), - name, - orig.kind.desc() - ) - .forget_guarantee() - } else { - // shadowing involving a label is only a warning, due to issues with - // labels and lifetimes not being macro-hygienic. - tcx.sess.struct_span_warn( - shadower.span, - &format!( - "{} name `{}` shadows a \ - {} name that is already in scope", - shadower.kind.desc(), - name, - orig.kind.desc() - ), - ) - }; - err.span_label(orig.span, "first declared here"); - err.span_label(shadower.span, format!("{} `{}` already in scope", orig.kind.desc(), name)); - err.emit(); -} - -// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning -// if one of the label shadows a lifetime or another label. -fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) { - struct GatherLabels<'a, 'tcx> { - tcx: TyCtxt<'tcx>, - scope: ScopeRef<'a>, - labels_in_fn: &'a mut Vec, - } - - let mut gather = - GatherLabels { tcx: ctxt.tcx, scope: ctxt.scope, labels_in_fn: &mut ctxt.labels_in_fn }; - gather.visit_body(body); - - impl<'v, 'a, 'tcx> Visitor<'v> for GatherLabels<'a, 'tcx> { - fn visit_expr(&mut self, ex: &hir::Expr<'_>) { - if let Some(label) = expression_label(ex) { - for prior_label in &self.labels_in_fn[..] { - // FIXME (#24278): non-hygienic comparison - if label.name == prior_label.name { - signal_shadowing_problem( - self.tcx, - label.name, - original_label(prior_label.span), - shadower_label(label.span), - ); - } - } - - check_if_label_shadows_lifetime(self.tcx, self.scope, label); - - self.labels_in_fn.push(label); - } - intravisit::walk_expr(self, ex) - } - } - - fn expression_label(ex: &hir::Expr<'_>) -> Option { - match ex.kind { - hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident), - hir::ExprKind::Block(_, Some(label)) => Some(label.ident), - _ => None, - } - } - - fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) { - loop { - match *scope { - Scope::Body { s, .. } - | Scope::Elision { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } - | Scope::Supertrait { s, .. } - | Scope::TraitRefBoundary { s, .. } => { - scope = s; - } - - Scope::Root => { - return; - } - - Scope::Binder { ref lifetimes, s, .. } => { - // FIXME (#24278): non-hygienic comparison - if let Some(def) = - lifetimes.get(&hir::ParamName::Plain(label.normalize_to_macros_2_0())) - { - signal_shadowing_problem( - tcx, - label.name, - original_lifetime(tcx.def_span(def.id().unwrap().expect_local())), - shadower_label(label.span), - ); - return; - } - scope = s; - } - } - } - } -} - fn compute_object_lifetime_defaults<'tcx>( tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, @@ -1774,10 +1610,9 @@ fn object_lifetime_defaults_for_item<'tcx>( impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { fn with(&mut self, wrap_scope: Scope<'_>, f: F) where - F: for<'b> FnOnce(ScopeRef<'_>, &mut LifetimeContext<'b, 'tcx>), + F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>), { let LifetimeContext { tcx, map, .. } = self; - let labels_in_fn = take(&mut self.labels_in_fn); let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults); let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots); let mut this = LifetimeContext { @@ -1785,16 +1620,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { map, scope: &wrap_scope, trait_definition_only: self.trait_definition_only, - labels_in_fn, xcrate_object_lifetime_defaults, missing_named_lifetime_spots, }; let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope)); { let _enter = span.enter(); - f(self.scope, &mut this); + f(&mut this); } - self.labels_in_fn = this.labels_in_fn; self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults; self.missing_named_lifetime_spots = this.missing_named_lifetime_spots; } @@ -1891,10 +1724,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope_type: BinderScopeType::Normal, allow_late_bound: true, }; - self.with(scope, move |old_scope, this| { - this.check_lifetime_params(old_scope, &generics.params); - walk(this); - }); + self.with(scope, walk); } fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 { @@ -2165,7 +1995,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { GenericArg::Type(ty) => { if let Some(<) = object_lifetime_defaults.get(i) { let scope = Scope::ObjectLifetimeDefault { lifetime: lt, s: self.scope }; - self.with(scope, |_, this| this.visit_ty(ty)); + self.with(scope, |this| this.visit_ty(ty)); } else { self.visit_ty(ty); } @@ -2222,15 +2052,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { type_def_id, binding.ident, ); - self.with(scope, |_, this| { + self.with(scope, |this| { let scope = Scope::Supertrait { lifetimes: lifetimes.unwrap_or_default(), s: this.scope, }; - this.with(scope, |_, this| this.visit_assoc_type_binding(binding)); + this.with(scope, |this| this.visit_assoc_type_binding(binding)); }); } else { - self.with(scope, |_, this| this.visit_assoc_type_binding(binding)); + self.with(scope, |this| this.visit_assoc_type_binding(binding)); } } } @@ -2346,7 +2176,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)), s: self.scope, }; - self.with(arg_scope, |_, this| { + self.with(arg_scope, |this| { for input in inputs { this.visit_ty(input); } @@ -2466,7 +2296,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { visitor.visit_ty(&inputs[0]); if let Set1::One(lifetime) = visitor.lifetime { let scope = Scope::Elision { elide: Elide::Exact(lifetime), s: self.scope }; - self.with(scope, |_, this| this.visit_ty(output)); + self.with(scope, |this| this.visit_ty(output)); return; } } @@ -2517,7 +2347,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { debug!(?elide); let scope = Scope::Elision { elide, s: self.scope }; - self.with(scope, |_, this| this.visit_ty(output)); + self.with(scope, |this| this.visit_ty(output)); struct GatherLifetimes<'a> { map: &'a NamedRegionMap, @@ -2789,101 +2619,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth)); } - fn check_lifetime_params( - &mut self, - old_scope: ScopeRef<'_>, - params: &'tcx [hir::GenericParam<'tcx>], - ) { - let lifetimes: Vec<_> = params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => { - Some((param, param.name.normalize_to_macros_2_0())) - } - _ => None, - }) - .collect(); - for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() { - if let hir::ParamName::Plain(_) = lifetime_i_name { - let name = lifetime_i_name.ident().name; - if name == kw::UnderscoreLifetime || name == kw::StaticLifetime { - self.tcx.sess.delay_span_bug( - lifetime_i.span, - &format!("invalid lifetime parameter name: `{}`", lifetime_i.name.ident()), - ); - } - } - - // It is a hard error to shadow a lifetime within the same scope. - for (lifetime_j, lifetime_j_name) in lifetimes.iter().skip(i + 1) { - if lifetime_i_name == lifetime_j_name { - struct_span_err!( - self.tcx.sess, - lifetime_j.span, - E0263, - "lifetime name `{}` declared twice in the same scope", - lifetime_j.name.ident() - ) - .span_label(lifetime_j.span, "declared twice") - .span_label(lifetime_i.span, "previous declaration here") - .emit(); - } - } - - // It is a soft error to shadow a lifetime within a parent scope. - self.check_lifetime_param_for_shadowing(old_scope, &lifetime_i); - } - } - - fn check_lifetime_param_for_shadowing( - &self, - mut old_scope: ScopeRef<'_>, - param: &'tcx hir::GenericParam<'tcx>, - ) { - for label in &self.labels_in_fn { - // FIXME (#24278): non-hygienic comparison - if param.name.ident().name == label.name { - signal_shadowing_problem( - self.tcx, - label.name, - original_label(label.span), - shadower_lifetime(¶m), - ); - return; - } - } - - loop { - match *old_scope { - Scope::Body { s, .. } - | Scope::Elision { s, .. } - | Scope::ObjectLifetimeDefault { s, .. } - | Scope::Supertrait { s, .. } - | Scope::TraitRefBoundary { s, .. } => { - old_scope = s; - } - - Scope::Root => { - return; - } - - Scope::Binder { ref lifetimes, s, .. } => { - if let Some(&def) = lifetimes.get(¶m.name.normalize_to_macros_2_0()) { - signal_shadowing_problem( - self.tcx, - param.name.ident().name, - original_lifetime(self.tcx.def_span(def.id().unwrap())), - shadower_lifetime(¶m), - ); - return; - } - - old_scope = s; - } - } - } - } - #[tracing::instrument(level = "debug", skip(self))] fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) { debug!( From 85cbd0bc185c4b9b36162a638c9ec3915df265b2 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 8 Dec 2021 22:40:16 +0100 Subject: [PATCH 2/9] Bless tests. --- src/test/ui/error-codes/E0263.stderr | 4 +- .../generic-associated-types/shadowing.stderr | 32 +- .../ui/hygiene/duplicate_lifetimes.stderr | 8 +- src/test/ui/hygiene/hygienic-labels-in-let.rs | 43 +-- .../ui/hygiene/hygienic-labels-in-let.stderr | 311 +---------------- src/test/ui/hygiene/hygienic-labels.rs | 43 +-- src/test/ui/hygiene/hygienic-labels.stderr | 313 +----------------- src/test/ui/label/label_misspelled.stderr | 96 ++++-- src/test/ui/label/label_misspelled_2.stderr | 38 ++- src/test/ui/lint/unused_labels.rs | 1 + src/test/ui/lint/unused_labels.stderr | 33 +- src/test/ui/loops/loop-break-value.stderr | 19 +- .../macros/macro-lifetime-used-with-labels.rs | 2 +- .../macro-lifetime-used-with-labels.stderr | 15 - .../ui/regions/regions-name-duplicated.rs | 6 +- .../ui/regions/regions-name-duplicated.stderr | 17 +- 16 files changed, 207 insertions(+), 774 deletions(-) delete mode 100644 src/test/ui/macros/macro-lifetime-used-with-labels.stderr diff --git a/src/test/ui/error-codes/E0263.stderr b/src/test/ui/error-codes/E0263.stderr index 4dae02b85c36c..56e4ef023794f 100644 --- a/src/test/ui/error-codes/E0263.stderr +++ b/src/test/ui/error-codes/E0263.stderr @@ -2,9 +2,9 @@ error[E0263]: lifetime name `'a` declared twice in the same scope --> $DIR/E0263.rs:1:16 | LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { - | -- ^^ declared twice + | -- ^^ lifetime `'a` already in scope | | - | previous declaration here + | first declared here error: aborting due to previous error diff --git a/src/test/ui/generic-associated-types/shadowing.stderr b/src/test/ui/generic-associated-types/shadowing.stderr index 857757f8940dc..be765920975b3 100644 --- a/src/test/ui/generic-associated-types/shadowing.stderr +++ b/src/test/ui/generic-associated-types/shadowing.stderr @@ -1,3 +1,19 @@ +error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope + --> $DIR/shadowing.rs:4:14 + | +LL | trait Shadow<'a> { + | -- first declared here +LL | type Bar<'a>; + | ^^ lifetime `'a` already in scope + +error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope + --> $DIR/shadowing.rs:13:14 + | +LL | impl<'a> NoShadow<'a> for &'a u32 { + | -- first declared here +LL | type Bar<'a> = i32; + | ^^ lifetime `'a` already in scope + error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters --> $DIR/shadowing.rs:18:14 | @@ -14,22 +30,6 @@ LL | impl NoShadowT for Option { LL | type Bar = i32; | ^ already used -error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope - --> $DIR/shadowing.rs:13:14 - | -LL | impl<'a> NoShadow<'a> for &'a u32 { - | -- first declared here -LL | type Bar<'a> = i32; - | ^^ lifetime `'a` already in scope - -error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope - --> $DIR/shadowing.rs:4:14 - | -LL | trait Shadow<'a> { - | -- first declared here -LL | type Bar<'a>; - | ^^ lifetime `'a` already in scope - error: aborting due to 4 previous errors Some errors have detailed explanations: E0403, E0496. diff --git a/src/test/ui/hygiene/duplicate_lifetimes.stderr b/src/test/ui/hygiene/duplicate_lifetimes.stderr index 4d41ebaa43733..ade411a25442b 100644 --- a/src/test/ui/hygiene/duplicate_lifetimes.stderr +++ b/src/test/ui/hygiene/duplicate_lifetimes.stderr @@ -2,12 +2,12 @@ error[E0263]: lifetime name `'a` declared twice in the same scope --> $DIR/duplicate_lifetimes.rs:8:14 | LL | fn g<$a, 'a>() {} - | ^^ declared twice + | ^^ lifetime `'a` already in scope ... LL | m!('a); | ------ | | | - | | previous declaration here + | | first declared here | in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) @@ -16,12 +16,12 @@ error[E0263]: lifetime name `'a` declared twice in the same scope --> $DIR/duplicate_lifetimes.rs:13:14 | LL | fn h<$a, 'a>() {} - | ^^ declared twice + | ^^ lifetime `'a` already in scope ... LL | n!('a); | ------ | | | - | | previous declaration here + | | first declared here | in this macro invocation | = note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.rs b/src/test/ui/hygiene/hygienic-labels-in-let.rs index 491855d7becd1..19f72f24459b3 100644 --- a/src/test/ui/hygiene/hygienic-labels-in-let.rs +++ b/src/test/ui/hygiene/hygienic-labels-in-let.rs @@ -13,38 +13,28 @@ macro_rules! loop_x { ($e: expr) => { // $e shouldn't be able to interact with this 'x - 'x: loop { $e } - //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - } + 'x: loop { + $e + } + }; } macro_rules! while_true { ($e: expr) => { // $e shouldn't be able to interact with this 'x - 'x: while 1 + 1 == 2 { $e } - //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - } + 'x: while 1 + 1 == 2 { + $e + } + }; } macro_rules! run_once { ($e: expr) => { // ditto - 'x: for _ in 0..1 { $e } - //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - } + 'x: for _ in 0..1 { + $e + } + }; } pub fn main() { @@ -63,7 +53,6 @@ pub fn main() { let k: isize = { 'x: for _ in 0..1 { //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope // ditto loop_x!(break 'x); i += 1; @@ -75,9 +64,6 @@ pub fn main() { let l: isize = { 'x: for _ in 0..1 { //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope // ditto while_true!(break 'x); i += 1; @@ -89,11 +75,6 @@ pub fn main() { let n: isize = { 'x: for _ in 0..1 { //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope // ditto run_once!(continue 'x); i += 1; diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.stderr b/src/test/ui/hygiene/hygienic-labels-in-let.stderr index 519e3c0880ac6..e1c284600ea23 100644 --- a/src/test/ui/hygiene/hygienic-labels-in-let.stderr +++ b/src/test/ui/hygiene/hygienic-labels-in-let.stderr @@ -1,334 +1,29 @@ warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:16:9 + --> $DIR/hygienic-labels-in-let.rs:54:9 | -LL | 'x: loop { $e } - | ^^ label `'x` already in scope -... LL | 'x: loop { | -- first declared here -LL | // this 'x should refer to the outer loop, lexically -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:64:9 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:64:9 - | -LL | 'x: loop { $e } - | -- first declared here ... LL | 'x: for _ in 0..1 { | ^^ label `'x` already in scope warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:16:9 + --> $DIR/hygienic-labels-in-let.rs:65:9 | -LL | 'x: loop { $e } - | ^^ label `'x` already in scope -... LL | 'x: loop { | -- first declared here ... -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:16:9 - | -LL | 'x: loop { $e } - | ^^ - | | - | first declared here - | label `'x` already in scope -... -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:16:9 - | -LL | 'x: loop { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:76:9 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:76:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:76:9 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... LL | 'x: for _ in 0..1 { | ^^ label `'x` already in scope warning: label name `'x` shadows a label name that is already in scope --> $DIR/hygienic-labels-in-let.rs:76:9 | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:27:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... LL | 'x: loop { | -- first declared here ... -LL | while_true!(break 'x); - | --------------------- in this macro invocation - | - = note: this warning originates in the macro `while_true` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:27:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... -LL | while_true!(break 'x); - | --------------------- in this macro invocation - | - = note: this warning originates in the macro `while_true` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:27:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | while_true!(break 'x); - | --------------------- in this macro invocation - | - = note: this warning originates in the macro `while_true` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:27:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { $e } | ^^ label `'x` already in scope -... -LL | while_true!(break 'x); - | --------------------- in this macro invocation - | - = note: this warning originates in the macro `while_true` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:27:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | while_true!(break 'x); - | --------------------- in this macro invocation - | - = note: this warning originates in the macro `while_true` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:90:9 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:90:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:90:9 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:90:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:90:9 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:90:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:39:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: loop { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:39:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:39:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:39:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:39:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:39:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:39:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) -warning: 28 warnings emitted +warning: 3 warnings emitted diff --git a/src/test/ui/hygiene/hygienic-labels.rs b/src/test/ui/hygiene/hygienic-labels.rs index c9f494b68b4a8..af8f928527347 100644 --- a/src/test/ui/hygiene/hygienic-labels.rs +++ b/src/test/ui/hygiene/hygienic-labels.rs @@ -10,38 +10,28 @@ macro_rules! loop_x { ($e: expr) => { // $e shouldn't be able to interact with this 'x - 'x: loop { $e } - //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - } + 'x: loop { + $e + } + }; } macro_rules! run_once { ($e: expr) => { // ditto - 'x: for _ in 0..1 { $e } - //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - } + 'x: for _ in 0..1 { + $e + } + }; } macro_rules! while_x { ($e: expr) => { // ditto - 'x: while 1 + 1 == 2 { $e } - //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - } + 'x: while 1 + 1 == 2 { + $e + } + }; } pub fn main() { @@ -53,7 +43,6 @@ pub fn main() { 'x: loop { //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope // ditto loop_x!(break 'x); @@ -62,9 +51,6 @@ pub fn main() { 'x: while 1 + 1 == 2 { //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope while_x!(break 'x); panic!("break doesn't act hygienically inside infinite while loop"); @@ -72,11 +58,6 @@ pub fn main() { 'x: for _ in 0..1 { //~^ WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope - //~| WARNING shadows a label name that is already in scope // ditto run_once!(continue 'x); diff --git a/src/test/ui/hygiene/hygienic-labels.stderr b/src/test/ui/hygiene/hygienic-labels.stderr index f0b891fe34979..df1f3c701904b 100644 --- a/src/test/ui/hygiene/hygienic-labels.stderr +++ b/src/test/ui/hygiene/hygienic-labels.stderr @@ -1,79 +1,14 @@ warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:13:9 + --> $DIR/hygienic-labels.rs:44:5 | -LL | 'x: loop { $e } - | ^^ label `'x` already in scope -... LL | 'x: for _ in 0..1 { | -- first declared here -LL | // this 'x should refer to the outer loop, lexically -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:54:5 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | 'x: loop { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:54:5 - | -LL | 'x: loop { $e } - | -- first declared here ... LL | 'x: loop { | ^^ label `'x` already in scope warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:13:9 - | -LL | 'x: loop { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:13:9 - | -LL | 'x: loop { $e } - | ^^ - | | - | first declared here - | label `'x` already in scope -... -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:13:9 - | -LL | 'x: loop { $e } - | ^^ label `'x` already in scope -... -LL | 'x: loop { - | -- first declared here -... -LL | loop_x!(break 'x); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `loop_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:63:5 + --> $DIR/hygienic-labels.rs:52:5 | LL | 'x: for _ in 0..1 { | -- first declared here @@ -82,253 +17,13 @@ LL | 'x: while 1 + 1 == 2 { | ^^ label `'x` already in scope warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:63:5 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:63:5 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:63:5 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:38:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | while_x!(break 'x); - | ------------------ in this macro invocation - | - = note: this warning originates in the macro `while_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:38:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... -LL | while_x!(break 'x); - | ------------------ in this macro invocation - | - = note: this warning originates in the macro `while_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:38:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: loop { - | -- first declared here -... -LL | while_x!(break 'x); - | ------------------ in this macro invocation - | - = note: this warning originates in the macro `while_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:38:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... -LL | while_x!(break 'x); - | ------------------ in this macro invocation - | - = note: this warning originates in the macro `while_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:38:9 - | -LL | 'x: while 1 + 1 == 2 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: while 1 + 1 == 2 { - | -- first declared here -... -LL | while_x!(break 'x); - | ------------------ in this macro invocation - | - = note: this warning originates in the macro `while_x` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:73:5 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:73:5 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:73:5 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:73:5 + --> $DIR/hygienic-labels.rs:59:5 | -LL | 'x: loop { $e } - | -- first declared here -... LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:73:5 - | -LL | 'x: while 1 + 1 == 2 { | -- first declared here ... LL | 'x: for _ in 0..1 { | ^^ label `'x` already in scope -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:73:5 - | -LL | 'x: while 1 + 1 == 2 { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:24:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:24:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:24:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: loop { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:24:9 - | -LL | 'x: loop { $e } - | -- first declared here -... -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:24:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: while 1 + 1 == 2 { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:24:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: while 1 + 1 == 2 { $e } - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:24:9 - | -LL | 'x: for _ in 0..1 { $e } - | ^^ label `'x` already in scope -... -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | run_once!(continue 'x); - | ---------------------- in this macro invocation - | - = note: this warning originates in the macro `run_once` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: 28 warnings emitted +warning: 3 warnings emitted diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr index 4b5b9e92ca09a..9d42aaa58cb21 100644 --- a/src/test/ui/label/label_misspelled.stderr +++ b/src/test/ui/label/label_misspelled.stderr @@ -2,7 +2,10 @@ error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:6:9 | LL | 'while_loop: while true { - | ----------- a label with a similar name exists + | ----------- + | | + | a label with a similar name exists + | a label with a similar name exists LL | LL | while_loop; | ^^^^^^^^^^ not found in this scope @@ -11,7 +14,10 @@ error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:11:9 | LL | 'while_let: while let Some(_) = Some(()) { - | ---------- a label with a similar name exists + | ---------- + | | + | a label with a similar name exists + | a label with a similar name exists LL | LL | while_let; | ^^^^^^^^^ not found in this scope @@ -20,7 +26,10 @@ error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:16:9 | LL | 'for_loop: for _ in 0..3 { - | --------- a label with a similar name exists + | --------- + | | + | a label with a similar name exists + | a label with a similar name exists LL | LL | for_loop; | ^^^^^^^^ not found in this scope @@ -29,7 +38,10 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:21:9 | LL | 'LOOP: loop { - | ----- a label with a similar name exists + | ----- + | | + | a label with a similar name exists + | a label with a similar name exists LL | LL | LOOP; | ^^^^ not found in this scope @@ -38,45 +50,81 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:28:15 | LL | 'LOOP: loop { - | ----- a label with a similar name exists + | ----- + | | + | a label with a similar name exists + | a label with a similar name exists LL | break LOOP; - | ^^^^ - | | - | not found in this scope - | help: use the similarly named label: `'LOOP` + | ^^^^ not found in this scope + | +help: use the similarly named label + | +LL | break 'LOOP; + | ~~~~~ +help: use the similarly named label + | +LL | break 'LOOP; + | ~~~~~ error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:32:15 | LL | 'while_loop: while true { - | ----------- a label with a similar name exists + | ----------- + | | + | a label with a similar name exists + | a label with a similar name exists LL | break while_loop; - | ^^^^^^^^^^ - | | - | not found in this scope - | help: use the similarly named label: `'while_loop` + | ^^^^^^^^^^ not found in this scope + | +help: use the similarly named label + | +LL | break 'while_loop; + | ~~~~~~~~~~~ +help: use the similarly named label + | +LL | break 'while_loop; + | ~~~~~~~~~~~ error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:36:15 | LL | 'while_let: while let Some(_) = Some(()) { - | ---------- a label with a similar name exists + | ---------- + | | + | a label with a similar name exists + | a label with a similar name exists LL | break while_let; - | ^^^^^^^^^ - | | - | not found in this scope - | help: use the similarly named label: `'while_let` + | ^^^^^^^^^ not found in this scope + | +help: use the similarly named label + | +LL | break 'while_let; + | ~~~~~~~~~~ +help: use the similarly named label + | +LL | break 'while_let; + | ~~~~~~~~~~ error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:40:15 | LL | 'for_loop: for _ in 0..3 { - | --------- a label with a similar name exists + | --------- + | | + | a label with a similar name exists + | a label with a similar name exists LL | break for_loop; - | ^^^^^^^^ - | | - | not found in this scope - | help: use the similarly named label: `'for_loop` + | ^^^^^^^^ not found in this scope + | +help: use the similarly named label + | +LL | break 'for_loop; + | ~~~~~~~~~ +help: use the similarly named label + | +LL | break 'for_loop; + | ~~~~~~~~~ warning: unused label --> $DIR/label_misspelled.rs:4:5 diff --git a/src/test/ui/label/label_misspelled_2.stderr b/src/test/ui/label/label_misspelled_2.stderr index 960646d9894d1..b618690340bb2 100644 --- a/src/test/ui/label/label_misspelled_2.stderr +++ b/src/test/ui/label/label_misspelled_2.stderr @@ -14,23 +14,41 @@ error[E0425]: cannot find value `b` in this scope --> $DIR/label_misspelled_2.rs:8:15 | LL | 'b: for _ in 0..1 { - | -- a label with a similar name exists + | -- + | | + | a label with a similar name exists + | a label with a similar name exists LL | break b; - | ^ - | | - | not found in this scope - | help: use the similarly named label: `'b` + | ^ not found in this scope + | +help: use the similarly named label + | +LL | break 'b; + | ~~ +help: use the similarly named label + | +LL | break 'b; + | ~~ error[E0425]: cannot find value `d` in this scope --> $DIR/label_misspelled_2.rs:14:15 | LL | d: for _ in 0..1 { - | - a label with a similar name exists + | - + | | + | a label with a similar name exists + | a label with a similar name exists LL | break d; - | ^ - | | - | not found in this scope - | help: use the similarly named label: `'d` + | ^ not found in this scope + | +help: use the similarly named label + | +LL | break 'd; + | ~~ +help: use the similarly named label + | +LL | break 'd; + | ~~ error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs index 8a3568f65f63e..fb9a9ae2648a6 100644 --- a/src/test/ui/lint/unused_labels.rs +++ b/src/test/ui/lint/unused_labels.rs @@ -61,6 +61,7 @@ fn main() { //~^ WARN unused label 'many_used_shadowed: for _ in 0..10 { //~^ WARN label name `'many_used_shadowed` shadows a label name that is already in scope + //~| WARN label name `'many_used_shadowed` shadows a label name that is already in scope if 1 % 2 == 0 { break 'many_used_shadowed; } else { diff --git a/src/test/ui/lint/unused_labels.stderr b/src/test/ui/lint/unused_labels.stderr index 4bb1a437d2409..ed9287d54a44e 100644 --- a/src/test/ui/lint/unused_labels.stderr +++ b/src/test/ui/lint/unused_labels.stderr @@ -1,3 +1,21 @@ +warning: label name `'many_used_shadowed` shadows a label name that is already in scope + --> $DIR/unused_labels.rs:62:9 + | +LL | 'many_used_shadowed: for _ in 0..10 { + | ------------------- first declared here +LL | +LL | 'many_used_shadowed: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope + +warning: label name `'many_used_shadowed` shadows a label name that is already in scope + --> $DIR/unused_labels.rs:62:9 + | +LL | 'many_used_shadowed: for _ in 0..10 { + | ------------------- first declared here +LL | +LL | 'many_used_shadowed: for _ in 0..10 { + | ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope + warning: unused label --> $DIR/unused_labels.rs:11:5 | @@ -41,25 +59,16 @@ LL | 'many_used_shadowed: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:72:5 + --> $DIR/unused_labels.rs:73:5 | LL | 'unused_loop_label: loop { | ^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:78:5 + --> $DIR/unused_labels.rs:79:5 | LL | 'unused_block_label: { | ^^^^^^^^^^^^^^^^^^^ -warning: label name `'many_used_shadowed` shadows a label name that is already in scope - --> $DIR/unused_labels.rs:62:9 - | -LL | 'many_used_shadowed: for _ in 0..10 { - | ------------------- first declared here -LL | -LL | 'many_used_shadowed: for _ in 0..10 { - | ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope - -warning: 9 warnings emitted +warning: 10 warnings emitted diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index ccb27c3507076..5698c2693b5ee 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -2,12 +2,21 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/loop-break-value.rs:95:15 | LL | 'LOOP: for _ in 0 .. 9 { - | ----- a label with a similar name exists + | ----- + | | + | a label with a similar name exists + | a label with a similar name exists LL | break LOOP; - | ^^^^ - | | - | not found in this scope - | help: use the similarly named label: `'LOOP` + | ^^^^ not found in this scope + | +help: use the similarly named label + | +LL | break 'LOOP; + | ~~~~~ +help: use the similarly named label + | +LL | break 'LOOP; + | ~~~~~ warning: denote infinite loops with `loop { ... }` --> $DIR/loop-break-value.rs:26:5 diff --git a/src/test/ui/macros/macro-lifetime-used-with-labels.rs b/src/test/ui/macros/macro-lifetime-used-with-labels.rs index 2e9da6f9dc88c..59017da3b696e 100644 --- a/src/test/ui/macros/macro-lifetime-used-with-labels.rs +++ b/src/test/ui/macros/macro-lifetime-used-with-labels.rs @@ -18,7 +18,7 @@ macro_rules! br { } macro_rules! br2 { ($b:lifetime) => { - 'b: loop { //~ WARNING `'b` shadows a label name that is already in scope + 'b: loop { break $b; // this $b should refer to the outer loop. } } diff --git a/src/test/ui/macros/macro-lifetime-used-with-labels.stderr b/src/test/ui/macros/macro-lifetime-used-with-labels.stderr deleted file mode 100644 index 69334e2119210..0000000000000 --- a/src/test/ui/macros/macro-lifetime-used-with-labels.stderr +++ /dev/null @@ -1,15 +0,0 @@ -warning: label name `'b` shadows a label name that is already in scope - --> $DIR/macro-lifetime-used-with-labels.rs:21:9 - | -LL | 'b: loop { - | ^^ label `'b` already in scope -... -LL | 'b: loop { - | -- first declared here -LL | br2!('b); - | -------- in this macro invocation - | - = note: this warning originates in the macro `br2` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: 1 warning emitted - diff --git a/src/test/ui/regions/regions-name-duplicated.rs b/src/test/ui/regions/regions-name-duplicated.rs index f2adf01531569..ee9549991ce24 100644 --- a/src/test/ui/regions/regions-name-duplicated.rs +++ b/src/test/ui/regions/regions-name-duplicated.rs @@ -1,5 +1,7 @@ -struct Foo<'a, 'a> { //~ ERROR lifetime name `'a` declared twice - x: &'a isize +struct Foo<'a, 'a> { + //~^ ERROR lifetime name `'a` declared twice + //~| ERROR parameter `'a` is never used [E0392] + x: &'a isize, } fn main() {} diff --git a/src/test/ui/regions/regions-name-duplicated.stderr b/src/test/ui/regions/regions-name-duplicated.stderr index a7e03a61adcf5..6d6e28c8479e5 100644 --- a/src/test/ui/regions/regions-name-duplicated.stderr +++ b/src/test/ui/regions/regions-name-duplicated.stderr @@ -2,10 +2,19 @@ error[E0263]: lifetime name `'a` declared twice in the same scope --> $DIR/regions-name-duplicated.rs:1:16 | LL | struct Foo<'a, 'a> { - | -- ^^ declared twice + | -- ^^ lifetime `'a` already in scope | | - | previous declaration here + | first declared here -error: aborting due to previous error +error[E0392]: parameter `'a` is never used + --> $DIR/regions-name-duplicated.rs:1:12 + | +LL | struct Foo<'a, 'a> { + | ^^ unused parameter + | + = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0263`. +Some errors have detailed explanations: E0263, E0392. +For more information about an error, try `rustc --explain E0263`. From 257d8fce3e38177c3cc357f1ce23db87b69e1682 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 21 Apr 2022 19:48:40 +0200 Subject: [PATCH 3/9] Do not report mixed label/lifetime shadowing. --- compiler/rustc_resolve/src/late.rs | 50 ++------- .../rustc_resolve/src/late/diagnostics.rs | 106 ++++++------------ 2 files changed, 45 insertions(+), 111 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 533302a758f17..efdedbebbea5e 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 b77bcaad3542e..552102be92c12 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(); } From 84e19930e341a9b68d55f1925c6c8ed43dadac49 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 21 Apr 2022 22:44:48 +0200 Subject: [PATCH 4/9] Bless tests. --- ...loops-reject-labels-shadowing-lifetimes.rs | 109 ------------------ ...s-reject-labels-shadowing-lifetimes.stderr | 104 ----------------- .../loops-reject-lifetime-shadowing-label.rs | 36 ------ ...ops-reject-lifetime-shadowing-label.stderr | 18 --- 4 files changed, 267 deletions(-) delete mode 100644 src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs delete mode 100644 src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.stderr delete mode 100644 src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs delete mode 100644 src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr diff --git a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs b/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs deleted file mode 100644 index 741ea0c1ca8bc..0000000000000 --- a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.rs +++ /dev/null @@ -1,109 +0,0 @@ -// Issue #21633: reject duplicate loop labels in function bodies. -// This is testing interaction between lifetime-params and labels. - -// check-pass - -#![allow(dead_code, unused_variables)] - -fn foo() { - fn foo<'a>() { - 'a: loop { break 'a; } - //~^ WARN label name `'a` shadows a lifetime name that is already in scope - } - - struct Struct<'b, 'c> { _f: &'b i8, _g: &'c i8 } - enum Enum<'d, 'e> { A(&'d i8), B(&'e i8) } - - impl<'d, 'e> Struct<'d, 'e> { - fn meth_okay() { - 'a: loop { break 'a; } - 'b: loop { break 'b; } - 'c: loop { break 'c; } - } - } - - impl <'d, 'e> Enum<'d, 'e> { - fn meth_okay() { - 'a: loop { break 'a; } - 'b: loop { break 'b; } - 'c: loop { break 'c; } - } - } - - impl<'bad, 'c> Struct<'bad, 'c> { - fn meth_bad(&self) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - - impl<'b, 'bad> Struct<'b, 'bad> { - fn meth_bad2(&self) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - - impl<'b, 'c> Struct<'b, 'c> { - fn meth_bad3<'bad>(x: &'bad i8) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - - fn meth_bad4<'a,'bad>(x: &'a i8, y: &'bad i8) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - - impl <'bad, 'e> Enum<'bad, 'e> { - fn meth_bad(&self) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - impl <'d, 'bad> Enum<'d, 'bad> { - fn meth_bad2(&self) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - impl <'d, 'e> Enum<'d, 'e> { - fn meth_bad3<'bad>(x: &'bad i8) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - - fn meth_bad4<'a,'bad>(x: &'bad i8) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - - trait HasDefaultMethod1<'bad> { - fn meth_okay() { - 'c: loop { break 'c; } - } - fn meth_bad(&self) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - trait HasDefaultMethod2<'a,'bad> { - fn meth_bad(&self) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } - trait HasDefaultMethod3<'a,'b> { - fn meth_bad<'bad>(&self) { - 'bad: loop { break 'bad; } - //~^ WARN label name `'bad` shadows a lifetime name that is already in scope - } - } -} - - -pub fn main() { - foo(); -} diff --git a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.stderr b/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.stderr deleted file mode 100644 index 0d96c0b3a35b6..0000000000000 --- a/src/test/ui/loops/loops-reject-labels-shadowing-lifetimes.stderr +++ /dev/null @@ -1,104 +0,0 @@ -warning: label name `'a` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:10:9 - | -LL | fn foo<'a>() { - | -- first declared here -LL | 'a: loop { break 'a; } - | ^^ lifetime `'a` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:35:13 - | -LL | impl<'bad, 'c> Struct<'bad, 'c> { - | ---- first declared here -LL | fn meth_bad(&self) { -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:42:13 - | -LL | impl<'b, 'bad> Struct<'b, 'bad> { - | ---- first declared here -LL | fn meth_bad2(&self) { -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:49:13 - | -LL | fn meth_bad3<'bad>(x: &'bad i8) { - | ---- first declared here -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:54:13 - | -LL | fn meth_bad4<'a,'bad>(x: &'a i8, y: &'bad i8) { - | ---- first declared here -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:61:13 - | -LL | impl <'bad, 'e> Enum<'bad, 'e> { - | ---- first declared here -LL | fn meth_bad(&self) { -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:67:13 - | -LL | impl <'d, 'bad> Enum<'d, 'bad> { - | ---- first declared here -LL | fn meth_bad2(&self) { -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:73:13 - | -LL | fn meth_bad3<'bad>(x: &'bad i8) { - | ---- first declared here -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:78:13 - | -LL | fn meth_bad4<'a,'bad>(x: &'bad i8) { - | ---- first declared here -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:88:13 - | -LL | trait HasDefaultMethod1<'bad> { - | ---- first declared here -... -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:94:13 - | -LL | trait HasDefaultMethod2<'a,'bad> { - | ---- first declared here -LL | fn meth_bad(&self) { -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: label name `'bad` shadows a lifetime name that is already in scope - --> $DIR/loops-reject-labels-shadowing-lifetimes.rs:100:13 - | -LL | fn meth_bad<'bad>(&self) { - | ---- first declared here -LL | 'bad: loop { break 'bad; } - | ^^^^ lifetime `'bad` already in scope - -warning: 12 warnings emitted - diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs deleted file mode 100644 index ce2d07eb06a4d..0000000000000 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.rs +++ /dev/null @@ -1,36 +0,0 @@ -// check-pass -#![feature(label_break_value)] -#![allow(dead_code, unused_variables)] - -// Issue #21633: reject duplicate loop labels and block labels in function bodies. -// -// Test rejection of lifetimes in *expressions* that shadow labels. - -fn foo() { - // Reusing lifetime `'a` in function item is okay. - fn foo<'a>(x: &'a i8) -> i8 { *x } - - // So is reusing `'a` in struct item - struct S1<'a> { x: &'a i8 } impl<'a> S1<'a> { fn m(&self) {} } - // and a method item - struct S2; impl S2 { fn m<'a>(&self) {} } - - let z = 3_i8; - - 'a: loop { - let b = Box::new(|x: &i8| *x) as Box Fn(&'a i8) -> i8>; - //~^ WARN lifetime name `'a` shadows a label name that is already in scope - assert_eq!((*b)(&z), z); - break 'a; - } - - 'b: { - let b = Box::new(|x: &()| ()) as Box Fn(&'b ())>; - //~^ WARN lifetime name `'b` shadows a label name that is already in scope - break 'b; - } -} - -pub fn main() { - foo(); -} diff --git a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr b/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr deleted file mode 100644 index 9702b71600b5e..0000000000000 --- a/src/test/ui/loops/loops-reject-lifetime-shadowing-label.stderr +++ /dev/null @@ -1,18 +0,0 @@ -warning: lifetime name `'a` shadows a label name that is already in scope - --> $DIR/loops-reject-lifetime-shadowing-label.rs:21:55 - | -LL | 'a: loop { - | -- first declared here -LL | let b = Box::new(|x: &i8| *x) as Box Fn(&'a i8) -> i8>; - | ^^ label `'a` already in scope - -warning: lifetime name `'b` shadows a label name that is already in scope - --> $DIR/loops-reject-lifetime-shadowing-label.rs:28:55 - | -LL | 'b: { - | -- first declared here -LL | let b = Box::new(|x: &()| ()) as Box Fn(&'b ())>; - | ^^ label `'b` already in scope - -warning: 2 warnings emitted - From be40b588953df73a9e766b644b7eac9e7d287b99 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Sun, 1 May 2022 13:07:57 +0200 Subject: [PATCH 5/9] Stop warning against unrelated labels. --- compiler/rustc_resolve/src/late.rs | 1 - src/test/ui/hygiene/hygienic-labels-in-let.rs | 3 - .../ui/hygiene/hygienic-labels-in-let.stderr | 29 ------ src/test/ui/hygiene/hygienic-labels.rs | 6 -- src/test/ui/hygiene/hygienic-labels.stderr | 29 ------ src/test/ui/label/label_misspelled.stderr | 96 +++++-------------- src/test/ui/label/label_misspelled_2.stderr | 38 ++------ src/test/ui/lint/unused_labels.rs | 1 - src/test/ui/lint/unused_labels.stderr | 15 +-- src/test/ui/loops/loop-break-value.stderr | 19 +--- .../loops/loops-reject-duplicate-labels-2.rs | 36 ------- .../loops-reject-duplicate-labels-2.stderr | 74 -------------- .../ui/loops/loops-reject-duplicate-labels.rs | 49 ---------- .../loops-reject-duplicate-labels.stderr | 74 -------------- 14 files changed, 42 insertions(+), 428 deletions(-) delete mode 100644 src/test/ui/hygiene/hygienic-labels-in-let.stderr delete mode 100644 src/test/ui/hygiene/hygienic-labels.stderr delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels-2.rs delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels-2.stderr delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels.rs delete mode 100644 src/test/ui/loops/loops-reject-duplicate-labels.stderr diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index efdedbebbea5e..5c9074773de13 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3151,7 +3151,6 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { diagnostics::signal_label_shadowing(self.r.session, orig_ident, label.ident) } if rib.kind.is_label_barrier() { - rib.bindings.insert(ident, id); break; } } diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.rs b/src/test/ui/hygiene/hygienic-labels-in-let.rs index 19f72f24459b3..8cf66f31a0a1d 100644 --- a/src/test/ui/hygiene/hygienic-labels-in-let.rs +++ b/src/test/ui/hygiene/hygienic-labels-in-let.rs @@ -52,7 +52,6 @@ pub fn main() { let k: isize = { 'x: for _ in 0..1 { - //~^ WARNING shadows a label name that is already in scope // ditto loop_x!(break 'x); i += 1; @@ -63,7 +62,6 @@ pub fn main() { let l: isize = { 'x: for _ in 0..1 { - //~^ WARNING shadows a label name that is already in scope // ditto while_true!(break 'x); i += 1; @@ -74,7 +72,6 @@ pub fn main() { let n: isize = { 'x: for _ in 0..1 { - //~^ WARNING shadows a label name that is already in scope // ditto run_once!(continue 'x); i += 1; diff --git a/src/test/ui/hygiene/hygienic-labels-in-let.stderr b/src/test/ui/hygiene/hygienic-labels-in-let.stderr deleted file mode 100644 index e1c284600ea23..0000000000000 --- a/src/test/ui/hygiene/hygienic-labels-in-let.stderr +++ /dev/null @@ -1,29 +0,0 @@ -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:54:9 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:65:9 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels-in-let.rs:76:9 - | -LL | 'x: loop { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: 3 warnings emitted - diff --git a/src/test/ui/hygiene/hygienic-labels.rs b/src/test/ui/hygiene/hygienic-labels.rs index af8f928527347..6a7d81f045bfc 100644 --- a/src/test/ui/hygiene/hygienic-labels.rs +++ b/src/test/ui/hygiene/hygienic-labels.rs @@ -42,23 +42,17 @@ pub fn main() { } 'x: loop { - //~^ WARNING shadows a label name that is already in scope - // ditto loop_x!(break 'x); panic!("break doesn't act hygienically inside infinite loop"); } 'x: while 1 + 1 == 2 { - //~^ WARNING shadows a label name that is already in scope - while_x!(break 'x); panic!("break doesn't act hygienically inside infinite while loop"); } 'x: for _ in 0..1 { - //~^ WARNING shadows a label name that is already in scope - // ditto run_once!(continue 'x); panic!("continue doesn't act hygienically inside for loop"); diff --git a/src/test/ui/hygiene/hygienic-labels.stderr b/src/test/ui/hygiene/hygienic-labels.stderr deleted file mode 100644 index df1f3c701904b..0000000000000 --- a/src/test/ui/hygiene/hygienic-labels.stderr +++ /dev/null @@ -1,29 +0,0 @@ -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:44:5 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | 'x: loop { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:52:5 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | 'x: while 1 + 1 == 2 { - | ^^ label `'x` already in scope - -warning: label name `'x` shadows a label name that is already in scope - --> $DIR/hygienic-labels.rs:59:5 - | -LL | 'x: for _ in 0..1 { - | -- first declared here -... -LL | 'x: for _ in 0..1 { - | ^^ label `'x` already in scope - -warning: 3 warnings emitted - diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr index 9d42aaa58cb21..4b5b9e92ca09a 100644 --- a/src/test/ui/label/label_misspelled.stderr +++ b/src/test/ui/label/label_misspelled.stderr @@ -2,10 +2,7 @@ error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:6:9 | LL | 'while_loop: while true { - | ----------- - | | - | a label with a similar name exists - | a label with a similar name exists + | ----------- a label with a similar name exists LL | LL | while_loop; | ^^^^^^^^^^ not found in this scope @@ -14,10 +11,7 @@ error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:11:9 | LL | 'while_let: while let Some(_) = Some(()) { - | ---------- - | | - | a label with a similar name exists - | a label with a similar name exists + | ---------- a label with a similar name exists LL | LL | while_let; | ^^^^^^^^^ not found in this scope @@ -26,10 +20,7 @@ error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:16:9 | LL | 'for_loop: for _ in 0..3 { - | --------- - | | - | a label with a similar name exists - | a label with a similar name exists + | --------- a label with a similar name exists LL | LL | for_loop; | ^^^^^^^^ not found in this scope @@ -38,10 +29,7 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:21:9 | LL | 'LOOP: loop { - | ----- - | | - | a label with a similar name exists - | a label with a similar name exists + | ----- a label with a similar name exists LL | LL | LOOP; | ^^^^ not found in this scope @@ -50,81 +38,45 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/label_misspelled.rs:28:15 | LL | 'LOOP: loop { - | ----- - | | - | a label with a similar name exists - | a label with a similar name exists + | ----- a label with a similar name exists LL | break LOOP; - | ^^^^ not found in this scope - | -help: use the similarly named label - | -LL | break 'LOOP; - | ~~~~~ -help: use the similarly named label - | -LL | break 'LOOP; - | ~~~~~ + | ^^^^ + | | + | not found in this scope + | help: use the similarly named label: `'LOOP` error[E0425]: cannot find value `while_loop` in this scope --> $DIR/label_misspelled.rs:32:15 | LL | 'while_loop: while true { - | ----------- - | | - | a label with a similar name exists - | a label with a similar name exists + | ----------- a label with a similar name exists LL | break while_loop; - | ^^^^^^^^^^ not found in this scope - | -help: use the similarly named label - | -LL | break 'while_loop; - | ~~~~~~~~~~~ -help: use the similarly named label - | -LL | break 'while_loop; - | ~~~~~~~~~~~ + | ^^^^^^^^^^ + | | + | not found in this scope + | help: use the similarly named label: `'while_loop` error[E0425]: cannot find value `while_let` in this scope --> $DIR/label_misspelled.rs:36:15 | LL | 'while_let: while let Some(_) = Some(()) { - | ---------- - | | - | a label with a similar name exists - | a label with a similar name exists + | ---------- a label with a similar name exists LL | break while_let; - | ^^^^^^^^^ not found in this scope - | -help: use the similarly named label - | -LL | break 'while_let; - | ~~~~~~~~~~ -help: use the similarly named label - | -LL | break 'while_let; - | ~~~~~~~~~~ + | ^^^^^^^^^ + | | + | not found in this scope + | help: use the similarly named label: `'while_let` error[E0425]: cannot find value `for_loop` in this scope --> $DIR/label_misspelled.rs:40:15 | LL | 'for_loop: for _ in 0..3 { - | --------- - | | - | a label with a similar name exists - | a label with a similar name exists + | --------- a label with a similar name exists LL | break for_loop; - | ^^^^^^^^ not found in this scope - | -help: use the similarly named label - | -LL | break 'for_loop; - | ~~~~~~~~~ -help: use the similarly named label - | -LL | break 'for_loop; - | ~~~~~~~~~ + | ^^^^^^^^ + | | + | not found in this scope + | help: use the similarly named label: `'for_loop` warning: unused label --> $DIR/label_misspelled.rs:4:5 diff --git a/src/test/ui/label/label_misspelled_2.stderr b/src/test/ui/label/label_misspelled_2.stderr index b618690340bb2..960646d9894d1 100644 --- a/src/test/ui/label/label_misspelled_2.stderr +++ b/src/test/ui/label/label_misspelled_2.stderr @@ -14,41 +14,23 @@ error[E0425]: cannot find value `b` in this scope --> $DIR/label_misspelled_2.rs:8:15 | LL | 'b: for _ in 0..1 { - | -- - | | - | a label with a similar name exists - | a label with a similar name exists + | -- a label with a similar name exists LL | break b; - | ^ not found in this scope - | -help: use the similarly named label - | -LL | break 'b; - | ~~ -help: use the similarly named label - | -LL | break 'b; - | ~~ + | ^ + | | + | not found in this scope + | help: use the similarly named label: `'b` error[E0425]: cannot find value `d` in this scope --> $DIR/label_misspelled_2.rs:14:15 | LL | d: for _ in 0..1 { - | - - | | - | a label with a similar name exists - | a label with a similar name exists + | - a label with a similar name exists LL | break d; - | ^ not found in this scope - | -help: use the similarly named label - | -LL | break 'd; - | ~~ -help: use the similarly named label - | -LL | break 'd; - | ~~ + | ^ + | | + | not found in this scope + | help: use the similarly named label: `'d` error: aborting due to 4 previous errors diff --git a/src/test/ui/lint/unused_labels.rs b/src/test/ui/lint/unused_labels.rs index fb9a9ae2648a6..8a3568f65f63e 100644 --- a/src/test/ui/lint/unused_labels.rs +++ b/src/test/ui/lint/unused_labels.rs @@ -61,7 +61,6 @@ fn main() { //~^ WARN unused label 'many_used_shadowed: for _ in 0..10 { //~^ WARN label name `'many_used_shadowed` shadows a label name that is already in scope - //~| WARN label name `'many_used_shadowed` shadows a label name that is already in scope if 1 % 2 == 0 { break 'many_used_shadowed; } else { diff --git a/src/test/ui/lint/unused_labels.stderr b/src/test/ui/lint/unused_labels.stderr index ed9287d54a44e..85adc9ab3bfbe 100644 --- a/src/test/ui/lint/unused_labels.stderr +++ b/src/test/ui/lint/unused_labels.stderr @@ -7,15 +7,6 @@ LL | LL | 'many_used_shadowed: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope -warning: label name `'many_used_shadowed` shadows a label name that is already in scope - --> $DIR/unused_labels.rs:62:9 - | -LL | 'many_used_shadowed: for _ in 0..10 { - | ------------------- first declared here -LL | -LL | 'many_used_shadowed: for _ in 0..10 { - | ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope - warning: unused label --> $DIR/unused_labels.rs:11:5 | @@ -59,16 +50,16 @@ LL | 'many_used_shadowed: for _ in 0..10 { | ^^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:73:5 + --> $DIR/unused_labels.rs:72:5 | LL | 'unused_loop_label: loop { | ^^^^^^^^^^^^^^^^^^ warning: unused label - --> $DIR/unused_labels.rs:79:5 + --> $DIR/unused_labels.rs:78:5 | LL | 'unused_block_label: { | ^^^^^^^^^^^^^^^^^^^ -warning: 10 warnings emitted +warning: 9 warnings emitted diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index 5698c2693b5ee..ccb27c3507076 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -2,21 +2,12 @@ error[E0425]: cannot find value `LOOP` in this scope --> $DIR/loop-break-value.rs:95:15 | LL | 'LOOP: for _ in 0 .. 9 { - | ----- - | | - | a label with a similar name exists - | a label with a similar name exists + | ----- a label with a similar name exists LL | break LOOP; - | ^^^^ not found in this scope - | -help: use the similarly named label - | -LL | break 'LOOP; - | ~~~~~ -help: use the similarly named label - | -LL | break 'LOOP; - | ~~~~~ + | ^^^^ + | | + | not found in this scope + | help: use the similarly named label: `'LOOP` warning: denote infinite loops with `loop { ... }` --> $DIR/loop-break-value.rs:26:5 diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs b/src/test/ui/loops/loops-reject-duplicate-labels-2.rs deleted file mode 100644 index 68a19a8f6f717..0000000000000 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.rs +++ /dev/null @@ -1,36 +0,0 @@ -// check-pass -#![feature(label_break_value)] - -// Issue #21633: reject duplicate loop labels and block labels in function bodies. -// -// This is testing the generalization (to the whole function body) -// discussed here: -// https://internals.rust-lang.org/t/psa-rejecting-duplicate-loop-labels/1833 - -#[allow(unused_labels)] -pub fn foo() { - { 'fl: for _ in 0..10 { break; } } - { 'fl: loop { break; } } //~ WARN label name `'fl` shadows a label name that is already in scope - { 'lf: loop { break; } } - { 'lf: for _ in 0..10 { break; } } //~ WARN label name `'lf` shadows a label name that is already in scope - { 'wl: while 2 > 1 { break; } } - { 'wl: loop { break; } } //~ WARN label name `'wl` shadows a label name that is already in scope - { 'lw: loop { break; } } - { 'lw: while 2 > 1 { break; } } //~ WARN label name `'lw` shadows a label name that is already in scope - { 'fw: for _ in 0..10 { break; } } - { 'fw: while 2 > 1 { break; } } //~ WARN label name `'fw` shadows a label name that is already in scope - { 'wf: while 2 > 1 { break; } } - { 'wf: for _ in 0..10 { break; } } //~ WARN label name `'wf` shadows a label name that is already in scope - { 'tl: while let Some(_) = None:: { break; } } - { 'tl: loop { break; } } //~ WARN label name `'tl` shadows a label name that is already in scope - { 'lt: loop { break; } } - { 'lt: while let Some(_) = None:: { break; } } - //~^ WARN label name `'lt` shadows a label name that is already in scope - { 'bl: {} } - { 'bl: {} } //~ WARN label name `'bl` shadows a label name that is already in scope -} - - -pub fn main() { - foo(); -} diff --git a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr b/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr deleted file mode 100644 index 2c372fcff7a12..0000000000000 --- a/src/test/ui/loops/loops-reject-duplicate-labels-2.stderr +++ /dev/null @@ -1,74 +0,0 @@ -warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:13:7 - | -LL | { 'fl: for _ in 0..10 { break; } } - | --- first declared here -LL | { 'fl: loop { break; } } - | ^^^ label `'fl` already in scope - -warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:15:7 - | -LL | { 'lf: loop { break; } } - | --- first declared here -LL | { 'lf: for _ in 0..10 { break; } } - | ^^^ label `'lf` already in scope - -warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:17:7 - | -LL | { 'wl: while 2 > 1 { break; } } - | --- first declared here -LL | { 'wl: loop { break; } } - | ^^^ label `'wl` already in scope - -warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:19:7 - | -LL | { 'lw: loop { break; } } - | --- first declared here -LL | { 'lw: while 2 > 1 { break; } } - | ^^^ label `'lw` already in scope - -warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:21:7 - | -LL | { 'fw: for _ in 0..10 { break; } } - | --- first declared here -LL | { 'fw: while 2 > 1 { break; } } - | ^^^ label `'fw` already in scope - -warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:23:7 - | -LL | { 'wf: while 2 > 1 { break; } } - | --- first declared here -LL | { 'wf: for _ in 0..10 { break; } } - | ^^^ label `'wf` already in scope - -warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:25:7 - | -LL | { 'tl: while let Some(_) = None:: { break; } } - | --- first declared here -LL | { 'tl: loop { break; } } - | ^^^ label `'tl` already in scope - -warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:27:7 - | -LL | { 'lt: loop { break; } } - | --- first declared here -LL | { 'lt: while let Some(_) = None:: { break; } } - | ^^^ label `'lt` already in scope - -warning: label name `'bl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels-2.rs:30:7 - | -LL | { 'bl: {} } - | --- first declared here -LL | { 'bl: {} } - | ^^^ label `'bl` already in scope - -warning: 9 warnings emitted - diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.rs b/src/test/ui/loops/loops-reject-duplicate-labels.rs deleted file mode 100644 index c34bcf3df1d76..0000000000000 --- a/src/test/ui/loops/loops-reject-duplicate-labels.rs +++ /dev/null @@ -1,49 +0,0 @@ -// check-pass -#![feature(label_break_value)] - -// Issue #21633: reject duplicate loop labels and block labels in function bodies. - -#[allow(unused_labels)] -fn foo() { - 'fl: for _ in 0..10 { break; } - 'fl: loop { break; } //~ WARN label name `'fl` shadows a label name that is already in scope - - 'lf: loop { break; } - 'lf: for _ in 0..10 { break; } //~ WARN label name `'lf` shadows a label name that is already in scope - 'wl: while 2 > 1 { break; } - 'wl: loop { break; } //~ WARN label name `'wl` shadows a label name that is already in scope - 'lw: loop { break; } - 'lw: while 2 > 1 { break; } //~ WARN label name `'lw` shadows a label name that is already in scope - 'fw: for _ in 0..10 { break; } - 'fw: while 2 > 1 { break; } //~ WARN label name `'fw` shadows a label name that is already in scope - 'wf: while 2 > 1 { break; } - 'wf: for _ in 0..10 { break; } //~ WARN label name `'wf` shadows a label name that is already in scope - 'tl: while let Some(_) = None:: { break; } - 'tl: loop { break; } //~ WARN label name `'tl` shadows a label name that is already in scope - 'lt: loop { break; } - 'lt: while let Some(_) = None:: { break; } - //~^ WARN label name `'lt` shadows a label name that is already in scope - 'bl: {} - 'bl: {} //~ WARN label name `'bl` shadows a label name that is already in scope -} - -// Note however that it is okay for the same label to be reused in -// different methods of one impl, as illustrated here. - -struct S; -impl S { - fn m1(&self) { 'okay: loop { break 'okay; } } - fn m2(&self) { 'okay: loop { break 'okay; } } - fn m3(&self) { 'okay: { break 'okay; } } - fn m4(&self) { 'okay: { break 'okay; } } -} - - -pub fn main() { - let s = S; - s.m1(); - s.m2(); - s.m3(); - s.m4(); - foo(); -} diff --git a/src/test/ui/loops/loops-reject-duplicate-labels.stderr b/src/test/ui/loops/loops-reject-duplicate-labels.stderr deleted file mode 100644 index 3bf3af763ecfc..0000000000000 --- a/src/test/ui/loops/loops-reject-duplicate-labels.stderr +++ /dev/null @@ -1,74 +0,0 @@ -warning: label name `'fl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:9:5 - | -LL | 'fl: for _ in 0..10 { break; } - | --- first declared here -LL | 'fl: loop { break; } - | ^^^ label `'fl` already in scope - -warning: label name `'lf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:12:5 - | -LL | 'lf: loop { break; } - | --- first declared here -LL | 'lf: for _ in 0..10 { break; } - | ^^^ label `'lf` already in scope - -warning: label name `'wl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:14:5 - | -LL | 'wl: while 2 > 1 { break; } - | --- first declared here -LL | 'wl: loop { break; } - | ^^^ label `'wl` already in scope - -warning: label name `'lw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:16:5 - | -LL | 'lw: loop { break; } - | --- first declared here -LL | 'lw: while 2 > 1 { break; } - | ^^^ label `'lw` already in scope - -warning: label name `'fw` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:18:5 - | -LL | 'fw: for _ in 0..10 { break; } - | --- first declared here -LL | 'fw: while 2 > 1 { break; } - | ^^^ label `'fw` already in scope - -warning: label name `'wf` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:20:5 - | -LL | 'wf: while 2 > 1 { break; } - | --- first declared here -LL | 'wf: for _ in 0..10 { break; } - | ^^^ label `'wf` already in scope - -warning: label name `'tl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:22:5 - | -LL | 'tl: while let Some(_) = None:: { break; } - | --- first declared here -LL | 'tl: loop { break; } - | ^^^ label `'tl` already in scope - -warning: label name `'lt` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:24:5 - | -LL | 'lt: loop { break; } - | --- first declared here -LL | 'lt: while let Some(_) = None:: { break; } - | ^^^ label `'lt` already in scope - -warning: label name `'bl` shadows a label name that is already in scope - --> $DIR/loops-reject-duplicate-labels.rs:27:5 - | -LL | 'bl: {} - | --- first declared here -LL | 'bl: {} - | ^^^ label `'bl` already in scope - -warning: 9 warnings emitted - From a265c49b252a932b06a94d5715013c8311989139 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 5 May 2022 20:49:48 +0200 Subject: [PATCH 6/9] Rebase fallout. --- .../ui/for-loop-while/label_break_value.rs | 6 +- .../for-loop-while/label_break_value.stderr | 28 --------- .../label_break_value_invalid.rs | 5 +- .../label_break_value_invalid.stderr | 63 +------------------ 4 files changed, 7 insertions(+), 95 deletions(-) delete mode 100644 src/test/ui/for-loop-while/label_break_value.stderr diff --git a/src/test/ui/for-loop-while/label_break_value.rs b/src/test/ui/for-loop-while/label_break_value.rs index 5776c0b1e0c77..ca9d71a7a8b66 100644 --- a/src/test/ui/for-loop-while/label_break_value.rs +++ b/src/test/ui/for-loop-while/label_break_value.rs @@ -102,7 +102,7 @@ fn label_break_match(c: u8, xe: u8, ye: i8) { 0 => break 'a 0, v if { if v % 2 == 0 { break 'a 1; }; v % 3 == 0 } => { x += 1; }, v if { 'b: { break 'b v == 5; } } => { x = 41; }, - _ => 'b: { //~ WARNING `'b` shadows a label + _ => 'b: { break 'b (); }, } @@ -128,8 +128,8 @@ fn label_break_macro() { 0 }; assert_eq!(x, 0); - let x: u8 = 'a: { //~ WARNING `'a` shadows a label - 'b: { //~ WARNING `'b` shadows a label + let x: u8 = 'a: { + 'b: { if true { mac1!('a, 1); } diff --git a/src/test/ui/for-loop-while/label_break_value.stderr b/src/test/ui/for-loop-while/label_break_value.stderr deleted file mode 100644 index b1eb3204fd599..0000000000000 --- a/src/test/ui/for-loop-while/label_break_value.stderr +++ /dev/null @@ -1,28 +0,0 @@ -warning: label name `'b` shadows a label name that is already in scope - --> $DIR/label_break_value.rs:105:18 - | -LL | v if { 'b: { break 'b v == 5; } } => { x = 41; }, - | -- first declared here -LL | _ => 'b: { - | ^^ label `'b` already in scope - -warning: label name `'a` shadows a label name that is already in scope - --> $DIR/label_break_value.rs:131:17 - | -LL | let x: u8 = 'a: { - | -- first declared here -... -LL | let x: u8 = 'a: { - | ^^ label `'a` already in scope - -warning: label name `'b` shadows a label name that is already in scope - --> $DIR/label_break_value.rs:132:9 - | -LL | 'b: { - | -- first declared here -... -LL | 'b: { - | ^^ label `'b` already in scope - -warning: 3 warnings emitted - diff --git a/src/test/ui/for-loop-while/label_break_value_invalid.rs b/src/test/ui/for-loop-while/label_break_value_invalid.rs index e603c8463b578..149bf17b83cba 100644 --- a/src/test/ui/for-loop-while/label_break_value_invalid.rs +++ b/src/test/ui/for-loop-while/label_break_value_invalid.rs @@ -20,14 +20,11 @@ fn lbv_macro_test_hygiene_respected() { macro_rules! mac3 { ($val:expr) => { 'a: { - //~^ WARNING `'a` shadows a label - //~| WARNING `'a` shadows a label - //~| WARNING `'a` shadows a label $val } }; } - let x: u8 = mac3!('b: { //~ WARNING `'b` shadows a label + let x: u8 = mac3!('b: { if true { break 'a 3; //~ ERROR undeclared label `'a` [E0426] } diff --git a/src/test/ui/for-loop-while/label_break_value_invalid.stderr b/src/test/ui/for-loop-while/label_break_value_invalid.stderr index 549b394e14b10..7182b8f598f19 100644 --- a/src/test/ui/for-loop-while/label_break_value_invalid.stderr +++ b/src/test/ui/for-loop-while/label_break_value_invalid.stderr @@ -10,7 +10,7 @@ LL | mac2!(2); = note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0426]: use of undeclared label `'a` - --> $DIR/label_break_value_invalid.rs:32:19 + --> $DIR/label_break_value_invalid.rs:29:19 | LL | let x: u8 = mac3!('b: { | -- a label with a similar name is reachable @@ -22,68 +22,11 @@ LL | break 'a 3; | help: try using similarly named label: `'b` error[E0426]: use of undeclared label `'a` - --> $DIR/label_break_value_invalid.rs:37:29 + --> $DIR/label_break_value_invalid.rs:34:29 | LL | let x: u8 = mac3!(break 'a 4); | ^^ undeclared label `'a` -warning: label name `'a` shadows a label name that is already in scope - --> $DIR/label_break_value_invalid.rs:22:13 - | -LL | let x: u8 = 'a: { - | -- first declared here -... -LL | 'a: { - | ^^ label `'a` already in scope -... -LL | let x: u8 = mac3!('b: { - | _________________- -LL | | if true { -LL | | break 'a 3; -LL | | } -LL | | 0 -LL | | }); - | |______- in this macro invocation - | - = note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'b` shadows a label name that is already in scope - --> $DIR/label_break_value_invalid.rs:30:23 - | -LL | 'b: { - | -- first declared here -... -LL | let x: u8 = mac3!('b: { - | ^^ label `'b` already in scope - -warning: label name `'a` shadows a label name that is already in scope - --> $DIR/label_break_value_invalid.rs:22:13 - | -LL | let x: u8 = 'a: { - | -- first declared here -... -LL | 'a: { - | ^^ label `'a` already in scope -... -LL | let x: u8 = mac3!(break 'a 4); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info) - -warning: label name `'a` shadows a label name that is already in scope - --> $DIR/label_break_value_invalid.rs:22:13 - | -LL | 'a: { - | ^^ - | | - | first declared here - | label `'a` already in scope -... -LL | let x: u8 = mac3!(break 'a 4); - | ----------------- in this macro invocation - | - = note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: aborting due to 3 previous errors; 4 warnings emitted +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0426`. From c75409d5e423d0ba21a44eb7c2bf11df6bcf6072 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Fri, 27 May 2022 11:29:18 +0200 Subject: [PATCH 7/9] Do not lower generic lifetime params when AST resolution emitted an error. --- compiler/rustc_ast_lowering/src/lib.rs | 21 ++++++++----------- compiler/rustc_resolve/src/late.rs | 7 +++++++ .../ui/regions/regions-name-duplicated.rs | 1 - .../ui/regions/regions-name-duplicated.stderr | 13 ++---------- 4 files changed, 18 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index e59bc9aa6b399..b55b2e7148e7c 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -1917,14 +1917,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> { let (name, kind) = match param.kind { GenericParamKind::Lifetime => { - let param_name = if param.ident.name == kw::StaticLifetime - || param.ident.name == kw::UnderscoreLifetime - { - ParamName::Error - } else { - let ident = self.lower_ident(param.ident); - ParamName::Plain(ident) - }; + // AST resolution emitted an error on those parameters, so we lower them using + // `ParamName::Error`. + let param_name = + if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) { + ParamName::Error + } else { + let ident = self.lower_ident(param.ident); + ParamName::Plain(ident) + }; let kind = hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }; @@ -1949,10 +1950,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ) } }; - let name = match name { - hir::ParamName::Plain(ident) => hir::ParamName::Plain(self.lower_ident(ident)), - name => name, - }; let hir_id = self.lower_node_id(param.id); self.lower_attrs(hir_id, ¶m.attrs); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5c9074773de13..06778b6c5514f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1939,6 +1939,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { param.ident, orig_is_param, ); + // Record lifetime res, so lowering knows there is something fishy. + self.record_lifetime_res(param.id, LifetimeRes::Error); + continue; } Entry::Vacant(entry) => { entry.insert(true); @@ -1966,6 +1969,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ) .span_label(param.ident.span, "`'_` is a reserved lifetime name") .emit(); + // Record lifetime res, so lowering knows there is something fishy. + self.record_lifetime_res(param.id, LifetimeRes::Error); continue; } @@ -1979,6 +1984,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { ) .span_label(param.ident.span, "'static is a reserved lifetime name") .emit(); + // Record lifetime res, so lowering knows there is something fishy. + self.record_lifetime_res(param.id, LifetimeRes::Error); continue; } diff --git a/src/test/ui/regions/regions-name-duplicated.rs b/src/test/ui/regions/regions-name-duplicated.rs index ee9549991ce24..4cf8b4401925d 100644 --- a/src/test/ui/regions/regions-name-duplicated.rs +++ b/src/test/ui/regions/regions-name-duplicated.rs @@ -1,6 +1,5 @@ struct Foo<'a, 'a> { //~^ ERROR lifetime name `'a` declared twice - //~| ERROR parameter `'a` is never used [E0392] x: &'a isize, } diff --git a/src/test/ui/regions/regions-name-duplicated.stderr b/src/test/ui/regions/regions-name-duplicated.stderr index 6d6e28c8479e5..303aa3389998b 100644 --- a/src/test/ui/regions/regions-name-duplicated.stderr +++ b/src/test/ui/regions/regions-name-duplicated.stderr @@ -6,15 +6,6 @@ LL | struct Foo<'a, 'a> { | | | first declared here -error[E0392]: parameter `'a` is never used - --> $DIR/regions-name-duplicated.rs:1:12 - | -LL | struct Foo<'a, 'a> { - | ^^ unused parameter - | - = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData` - -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0263, E0392. -For more information about an error, try `rustc --explain E0263`. +For more information about this error, try `rustc --explain E0263`. From 86bd99060c5f2b60e27c6afa5ad9c904333cb746 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 2 Jun 2022 20:35:14 +0200 Subject: [PATCH 8/9] Reuse resolve_label to check lifetime shadowing. --- compiler/rustc_resolve/src/late.rs | 53 +++++++------------ .../rustc_resolve/src/late/diagnostics.rs | 16 +++--- 2 files changed, 29 insertions(+), 40 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 06778b6c5514f..5c968655e29ec 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1548,13 +1548,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { /// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved /// label and reports an error if the label is not found or is unreachable. - fn resolve_label(&mut self, mut label: Ident) -> Option { + fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'a>> { let mut suggestion = None; - // Preserve the original span so that errors contain "in this macro invocation" - // information. - let original_span = label.span; - for i in (0..self.label_ribs.len()).rev() { let rib = &self.label_ribs[i]; @@ -1570,18 +1566,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { if let Some((ident, id)) = rib.bindings.get_key_value(&ident) { let definition_span = ident.span; return if self.is_label_valid_from_rib(i) { - Some(*id) + Ok((*id, definition_span)) } else { - self.report_error( - original_span, - ResolutionError::UnreachableLabel { - name: label.name, - definition_span, - suggestion, - }, - ); - - None + Err(ResolutionError::UnreachableLabel { + name: label.name, + definition_span, + suggestion, + }) }; } @@ -1590,11 +1581,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label)); } - self.report_error( - original_span, - ResolutionError::UndeclaredLabel { name: label.name, suggestion }, - ); - None + Err(ResolutionError::UndeclaredLabel { name: label.name, suggestion }) } /// Determine whether or not a label from the `rib_index`th label rib is reachable. @@ -3152,17 +3139,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { self.diagnostic_metadata.unused_labels.insert(id, label.ident.span); } - let ident = label.ident.normalize_to_macro_rules(); - for rib in self.label_ribs.iter_mut().rev() { - 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() { - break; - } + if let Ok((_, orig_span)) = self.resolve_label(label.ident) { + diagnostics::signal_label_shadowing(self.r.session, orig_span, label.ident) } self.with_label_rib(NormalRibKind, |this| { + let ident = label.ident.normalize_to_macro_rules(); this.label_ribs.last_mut().unwrap().bindings.insert(ident, id); f(this); }); @@ -3266,10 +3248,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { } ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => { - if let Some(node_id) = self.resolve_label(label.ident) { - // Since this res is a label, it is never read. - self.r.label_res_map.insert(expr.id, node_id); - self.diagnostic_metadata.unused_labels.remove(&node_id); + match self.resolve_label(label.ident) { + Ok((node_id, _)) => { + // Since this res is a label, it is never read. + self.r.label_res_map.insert(expr.id, node_id); + self.diagnostic_metadata.unused_labels.remove(&node_id); + } + Err(error) => { + self.report_error(label.ident.span, error); + } } // visit `break` argument if any diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 552102be92c12..6d5318ae6f780 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2066,15 +2066,17 @@ pub fn signal_lifetime_shadowing( 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) { +/// Shadowing involving a label is only a warning for historical reasons. +//FIXME: make this a proper lint. +pub fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident) { + let name = shadower.name; + let shadower = shadower.span; let mut err = sess.struct_span_warn( - shadower.span, - &format!("label name `{}` shadows a label name that is already in scope", orig.name), + shadower, + &format!("label name `{}` shadows a label name that is already in scope", name), ); - err.span_label(orig.span, "first declared here"); - err.span_label(shadower.span, format!("label `{}` already in scope", orig.name)); + err.span_label(orig, "first declared here"); + err.span_label(shadower, format!("label `{}` already in scope", name)); err.emit(); } From 2aa9c703ce9ce9c69d466481b2fda3268db64f3e Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Thu, 2 Jun 2022 20:46:40 +0200 Subject: [PATCH 9/9] Use the same message as type & const generics. --- .../src/error_codes/E0263.md | 4 +- compiler/rustc_resolve/src/late.rs | 48 ++++++++----------- .../rustc_resolve/src/late/diagnostics.rs | 31 ++++-------- src/test/ui/error-codes/E0263.rs | 2 +- src/test/ui/error-codes/E0263.stderr | 8 ++-- src/test/ui/hygiene/duplicate_lifetimes.rs | 4 +- .../ui/hygiene/duplicate_lifetimes.stderr | 14 +++--- .../ui/regions/regions-name-duplicated.rs | 2 +- .../ui/regions/regions-name-duplicated.stderr | 8 ++-- 9 files changed, 50 insertions(+), 71 deletions(-) diff --git a/compiler/rustc_error_codes/src/error_codes/E0263.md b/compiler/rustc_error_codes/src/error_codes/E0263.md index 37271ac692d55..2d1ac40264de1 100644 --- a/compiler/rustc_error_codes/src/error_codes/E0263.md +++ b/compiler/rustc_error_codes/src/error_codes/E0263.md @@ -1,8 +1,10 @@ +#### Note: this error code is no longer emitted by the compiler. + A lifetime was declared more than once in the same scope. Erroneous code example: -```compile_fail,E0263 +```compile_fail,E0403 fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error! } ``` diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 5c968655e29ec..288c89b0189c4 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1885,9 +1885,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(); + // Store all seen lifetimes names from outer scopes. + let mut seen_lifetimes = FxHashSet::default(); // We also can't shadow bindings from the parent item if let AssocItemRibKind = kind { @@ -1905,7 +1904,7 @@ 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, false))); + seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| *ident)); if let LifetimeRibKind::Item = rib.kind { break; } @@ -1915,35 +1914,28 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { let ident = param.ident.normalize_to_macros_2_0(); debug!("with_generic_param_rib: {}", param.id); - if let GenericParamKind::Lifetime = param.kind { - match seen_lifetimes.entry(ident) { - Entry::Occupied(entry) => { - let original = *entry.key(); - let orig_is_param = *entry.get(); - diagnostics::signal_lifetime_shadowing( - self.r.session, - original, - param.ident, - orig_is_param, - ); + if let GenericParamKind::Lifetime = param.kind + && let Some(&original) = seen_lifetimes.get(&ident) + { + diagnostics::signal_lifetime_shadowing(self.r.session, original, param.ident); + // Record lifetime res, so lowering knows there is something fishy. + self.record_lifetime_res(param.id, LifetimeRes::Error); + continue; + } + + match seen_bindings.entry(ident) { + Entry::Occupied(entry) => { + let span = *entry.get(); + let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); + self.report_error(param.ident.span, err); + if let GenericParamKind::Lifetime = param.kind { // Record lifetime res, so lowering knows there is something fishy. self.record_lifetime_res(param.id, LifetimeRes::Error); continue; } - Entry::Vacant(entry) => { - entry.insert(true); - } } - } else { - match seen_bindings.entry(ident) { - Entry::Occupied(entry) => { - let span = *entry.get(); - let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); - self.report_error(param.ident.span, err); - } - Entry::Vacant(entry) => { - entry.insert(param.ident.span); - } + Entry::Vacant(entry) => { + entry.insert(param.ident.span); } } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6d5318ae6f780..9213652e35f8e 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2038,29 +2038,14 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { } /// 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 { - struct_span_err!( - sess, - shadower.span, - E0496, - "lifetime name `{}` shadows a lifetime name that is already in scope", - orig.name, - ) - }; +pub fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: Ident) { + let mut err = struct_span_err!( + sess, + shadower.span, + 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!("lifetime `{}` already in scope", orig.name)); err.emit(); diff --git a/src/test/ui/error-codes/E0263.rs b/src/test/ui/error-codes/E0263.rs index 4376437823cf6..92917678e4c02 100644 --- a/src/test/ui/error-codes/E0263.rs +++ b/src/test/ui/error-codes/E0263.rs @@ -1,5 +1,5 @@ fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { - //~^ ERROR E0263 + //~^ ERROR E0403 } fn main() {} diff --git a/src/test/ui/error-codes/E0263.stderr b/src/test/ui/error-codes/E0263.stderr index 56e4ef023794f..e3f9aea296a2c 100644 --- a/src/test/ui/error-codes/E0263.stderr +++ b/src/test/ui/error-codes/E0263.stderr @@ -1,11 +1,11 @@ -error[E0263]: lifetime name `'a` declared twice in the same scope +error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters --> $DIR/E0263.rs:1:16 | LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { - | -- ^^ lifetime `'a` already in scope + | -- ^^ already used | | - | first declared here + | first use of `'a` error: aborting due to previous error -For more information about this error, try `rustc --explain E0263`. +For more information about this error, try `rustc --explain E0403`. diff --git a/src/test/ui/hygiene/duplicate_lifetimes.rs b/src/test/ui/hygiene/duplicate_lifetimes.rs index e7312b51dbcb8..8971fb62626cb 100644 --- a/src/test/ui/hygiene/duplicate_lifetimes.rs +++ b/src/test/ui/hygiene/duplicate_lifetimes.rs @@ -5,12 +5,12 @@ #[rustc_macro_transparency = "semitransparent"] macro m($a:lifetime) { - fn g<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice + fn g<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter } #[rustc_macro_transparency = "transparent"] macro n($a:lifetime) { - fn h<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice + fn h<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter } m!('a); diff --git a/src/test/ui/hygiene/duplicate_lifetimes.stderr b/src/test/ui/hygiene/duplicate_lifetimes.stderr index ade411a25442b..9f1a75147272d 100644 --- a/src/test/ui/hygiene/duplicate_lifetimes.stderr +++ b/src/test/ui/hygiene/duplicate_lifetimes.stderr @@ -1,31 +1,31 @@ -error[E0263]: lifetime name `'a` declared twice in the same scope +error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters --> $DIR/duplicate_lifetimes.rs:8:14 | LL | fn g<$a, 'a>() {} - | ^^ lifetime `'a` already in scope + | ^^ already used ... LL | m!('a); | ------ | | | - | | first declared here + | | first use of `'a` | in this macro invocation | = note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0263]: lifetime name `'a` declared twice in the same scope +error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters --> $DIR/duplicate_lifetimes.rs:13:14 | LL | fn h<$a, 'a>() {} - | ^^ lifetime `'a` already in scope + | ^^ already used ... LL | n!('a); | ------ | | | - | | first declared here + | | first use of `'a` | in this macro invocation | = note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0263`. +For more information about this error, try `rustc --explain E0403`. diff --git a/src/test/ui/regions/regions-name-duplicated.rs b/src/test/ui/regions/regions-name-duplicated.rs index 4cf8b4401925d..f6616591a3df2 100644 --- a/src/test/ui/regions/regions-name-duplicated.rs +++ b/src/test/ui/regions/regions-name-duplicated.rs @@ -1,5 +1,5 @@ struct Foo<'a, 'a> { - //~^ ERROR lifetime name `'a` declared twice + //~^ ERROR the name `'a` is already used for a generic parameter x: &'a isize, } diff --git a/src/test/ui/regions/regions-name-duplicated.stderr b/src/test/ui/regions/regions-name-duplicated.stderr index 303aa3389998b..cef73c18d371e 100644 --- a/src/test/ui/regions/regions-name-duplicated.stderr +++ b/src/test/ui/regions/regions-name-duplicated.stderr @@ -1,11 +1,11 @@ -error[E0263]: lifetime name `'a` declared twice in the same scope +error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters --> $DIR/regions-name-duplicated.rs:1:16 | LL | struct Foo<'a, 'a> { - | -- ^^ lifetime `'a` already in scope + | -- ^^ already used | | - | first declared here + | first use of `'a` error: aborting due to previous error -For more information about this error, try `rustc --explain E0263`. +For more information about this error, try `rustc --explain E0403`.