1
Fork 0

Auto merge of #96296 - cjgillot:remove-label-lt-shadow, r=petrochenkov

Remove label/lifetime shadowing warnings

This PR removes some pre-1.0 shadowing warnings for labels and lifetimes.

The current behaviour of the compiler is to warn
* labels that shadow unrelated labels in the same function --> removed
```rust
'a: loop {}
'a: loop {} // STOP WARNING
```

* labels that shadow enclosing labels --> kept, but only if shadowing is hygienic
```rust
'a: loop {
  'a: loop {} // KEEP WARNING
}
```

* labels that shadow lifetime --> removed
```rust
fn foo<'a>() {
  'a: loop {} // STOP WARNING
}
```

* lifetimes that shadow labels --> removed
```rust
'a: loop {
  let b = Box::new(|x: &i8| *x) as Box<dyn for <'a> Fn(&'a i8) -> i8>; // STOP WARNING
}
```

* lifetimes that shadow lifetimes --> kept
```rust
fn foo<'a>() {
  let b = Box::new(|x: &i8| *x) as Box<dyn for <'a> Fn(&'a i8) -> i8>; // KEEP WARNING
}
```

Closes https://github.com/rust-lang/rust/issues/31745.

-----

From `@petrochenkov` in https://github.com/rust-lang/rust/pull/95781#issuecomment-1105199014
> I think we should remove these silly checks entirely.
> They were introduced long time ago in case some new language features appear and require this space.
> Now we have another mechanism for such language changes - editions, and if "lifetimes in expressions" or something like that needs to be introduced it could be introduced as an edition change.
> However, there was no plans to introduce anything like for years, so it's unlikely that even the edition mechanism will be necessary.

r? rust-lang/lang
This commit is contained in:
bors 2022-06-03 07:27:09 +00:00
commit 3a90bedb33
31 changed files with 223 additions and 1751 deletions

View file

@ -1848,14 +1848,15 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> { fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> {
let (name, kind) = match param.kind { let (name, kind) = match param.kind {
GenericParamKind::Lifetime => { GenericParamKind::Lifetime => {
let param_name = if param.ident.name == kw::StaticLifetime // AST resolution emitted an error on those parameters, so we lower them using
|| param.ident.name == kw::UnderscoreLifetime // `ParamName::Error`.
{ let param_name =
ParamName::Error if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
} else { ParamName::Error
let ident = self.lower_ident(param.ident); } else {
ParamName::Plain(ident) let ident = self.lower_ident(param.ident);
}; ParamName::Plain(ident)
};
let kind = let kind =
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }; hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
@ -1880,10 +1881,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); let hir_id = self.lower_node_id(param.id);
self.lower_attrs(hir_id, &param.attrs); self.lower_attrs(hir_id, &param.attrs);

View file

@ -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. A lifetime was declared more than once in the same scope.
Erroneous code example: Erroneous code example:
```compile_fail,E0263 ```compile_fail,E0403
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error! fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error!
} }
``` ```

View file

@ -172,6 +172,23 @@ impl RibKind<'_> {
AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true, 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. /// A single local scope.
@ -732,7 +749,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
// Create a value rib for the function. // Create a value rib for the function.
self.with_rib(ValueNS, rib_kind, |this| { self.with_rib(ValueNS, rib_kind, |this| {
// Create a label rib for the function. // 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()); let async_node_id = fn_kind.header().and_then(|h| h.asyncness.opt_return_id());
if let FnKind::Fn(_, _, _, _, generics, _) = fn_kind { if let FnKind::Fn(_, _, _, _, generics, _) = fn_kind {
@ -1531,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 /// 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. /// label and reports an error if the label is not found or is unreachable.
fn resolve_label(&mut self, mut label: Ident) -> Option<NodeId> { fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'a>> {
let mut suggestion = None; 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() { for i in (0..self.label_ribs.len()).rev() {
let rib = &self.label_ribs[i]; let rib = &self.label_ribs[i];
@ -1553,18 +1566,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
if let Some((ident, id)) = rib.bindings.get_key_value(&ident) { if let Some((ident, id)) = rib.bindings.get_key_value(&ident) {
let definition_span = ident.span; let definition_span = ident.span;
return if self.is_label_valid_from_rib(i) { return if self.is_label_valid_from_rib(i) {
Some(*id) Ok((*id, definition_span))
} else { } else {
self.report_error( Err(ResolutionError::UnreachableLabel {
original_span, name: label.name,
ResolutionError::UnreachableLabel { definition_span,
name: label.name, suggestion,
definition_span, })
suggestion,
},
);
None
}; };
} }
@ -1573,11 +1581,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label)); suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label));
} }
self.report_error( Err(ResolutionError::UndeclaredLabel { name: label.name, suggestion })
original_span,
ResolutionError::UndeclaredLabel { name: label.name, suggestion },
);
None
} }
/// Determine whether or not a label from the `rib_index`th label rib is reachable. /// Determine whether or not a label from the `rib_index`th label rib is reachable.
@ -1585,22 +1589,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let ribs = &self.label_ribs[rib_index + 1..]; let ribs = &self.label_ribs[rib_index + 1..];
for rib in ribs { for rib in ribs {
match rib.kind { if rib.kind.is_label_barrier() {
NormalRibKind | MacroDefinition(..) => { return false;
// Nothing to do. Continue.
}
AssocItemRibKind
| ClosureOrAsyncRibKind
| FnItemRibKind
| ItemRibKind(..)
| ConstantItemRibKind(..)
| ModuleRibKind(..)
| ForwardGenericParamBanRibKind
| ConstParamTyRibKind
| InlineAsmSymRibKind => {
return false;
}
} }
} }
@ -1895,6 +1885,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
let mut function_value_rib = Rib::new(kind); let mut function_value_rib = Rib::new(kind);
let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind); let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
let mut seen_bindings = FxHashMap::default(); let mut seen_bindings = 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 // We also can't shadow bindings from the parent item
if let AssocItemRibKind = kind { if let AssocItemRibKind = kind {
@ -1910,16 +1902,36 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
add_bindings_for_ns(TypeNS); 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));
if let LifetimeRibKind::Item = rib.kind {
break;
}
}
for param in params { for param in params {
let ident = param.ident.normalize_to_macros_2_0(); let ident = param.ident.normalize_to_macros_2_0();
debug!("with_generic_param_rib: {}", param.id); debug!("with_generic_param_rib: {}", param.id);
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) { match seen_bindings.entry(ident) {
Entry::Occupied(entry) => { Entry::Occupied(entry) => {
let span = *entry.get(); let span = *entry.get();
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span); let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
if !matches!(param.kind, GenericParamKind::Lifetime) { self.report_error(param.ident.span, err);
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::Vacant(entry) => {
@ -1936,6 +1948,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
) )
.span_label(param.ident.span, "`'_` is a reserved lifetime name") .span_label(param.ident.span, "`'_` is a reserved lifetime name")
.emit(); .emit();
// Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_res(param.id, LifetimeRes::Error);
continue; continue;
} }
@ -1949,6 +1963,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
) )
.span_label(param.ident.span, "'static is a reserved lifetime name") .span_label(param.ident.span, "'static is a reserved lifetime name")
.emit(); .emit();
// Record lifetime res, so lowering knows there is something fishy.
self.record_lifetime_res(param.id, LifetimeRes::Error);
continue; continue;
} }
@ -3114,6 +3130,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
if label.ident.as_str().as_bytes()[1] != b'_' { if label.ident.as_str().as_bytes()[1] != b'_' {
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span); self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
} }
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| { self.with_label_rib(NormalRibKind, |this| {
let ident = label.ident.normalize_to_macro_rules(); let ident = label.ident.normalize_to_macro_rules();
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id); this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
@ -3219,10 +3240,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
} }
ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => { ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
if let Some(node_id) = self.resolve_label(label.ident) { match self.resolve_label(label.ident) {
// Since this res is a label, it is never read. Ok((node_id, _)) => {
self.r.label_res_map.insert(expr.id, node_id); // Since this res is a label, it is never read.
self.diagnostic_metadata.unused_labels.remove(&node_id); 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 // visit `break` argument if any

View file

@ -25,6 +25,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
use rustc_hir::PrimTy; use rustc_hir::PrimTy;
use rustc_session::lint; use rustc_session::lint;
use rustc_session::parse::feature_err; use rustc_session::parse::feature_err;
use rustc_session::Session;
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind; use rustc_span::hygiene::MacroKind;
use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::lev_distance::find_best_match_for_name;
@ -2036,6 +2037,34 @@ 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) {
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();
}
/// 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,
&format!("label name `{}` shadows a label name that is already in scope", name),
);
err.span_label(orig, "first declared here");
err.span_label(shadower, format!("label `{}` already in scope", name));
err.emit();
}
impl<'tcx> LifetimeContext<'_, 'tcx> { impl<'tcx> LifetimeContext<'_, 'tcx> {
pub(crate) fn report_missing_lifetime_specifiers( pub(crate) fn report_missing_lifetime_specifiers(
&self, &self,

View file

@ -23,7 +23,7 @@ use rustc_middle::middle::resolve_lifetime::*;
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt}; use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
use rustc_middle::{bug, span_bug}; use rustc_middle::{bug, span_bug};
use rustc_span::def_id::DefId; 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 rustc_span::Span;
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::Cell; use std::cell::Cell;
@ -161,9 +161,6 @@ pub(crate) struct LifetimeContext<'a, 'tcx> {
/// we eventually need lifetimes resolve for trait items. /// we eventually need lifetimes resolve for trait items.
trait_definition_only: bool, trait_definition_only: bool,
/// List of labels in the function/method currently under analysis.
labels_in_fn: Vec<Ident>,
/// Cache for cross-crate per-definition object lifetime defaults. /// Cache for cross-crate per-definition object lifetime defaults.
xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>, xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
@ -434,7 +431,6 @@ fn do_resolve(
map: &mut named_region_map, map: &mut named_region_map,
scope: ROOT_SCOPE, scope: ROOT_SCOPE,
trait_definition_only, trait_definition_only,
labels_in_fn: vec![],
xcrate_object_lifetime_defaults: Default::default(), xcrate_object_lifetime_defaults: Default::default(),
missing_named_lifetime_spots: vec![], 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) { 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); 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); this.visit_body(body);
}); });
self.labels_in_fn = saved;
} }
fn visit_fn( fn visit_fn(
@ -683,9 +675,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: true, allow_late_bound: true,
}; };
self.with(scope, move |_old_scope, this| { self.with(scope, move |this| intravisit::walk_fn(this, fk, fd, b, s, hir_id));
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(..) => { hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
// No lifetime parameters, but implied 'static. // No lifetime parameters, but implied 'static.
let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE }; 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 { .. }) => { hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => {
// Opaque types are visited when we visit the // Opaque types are visited when we visit the
@ -807,10 +797,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
s: ROOT_SCOPE, s: ROOT_SCOPE,
allow_late_bound: false, allow_late_bound: false,
}; };
self.with(scope, |old_scope, this| { self.with(scope, |this| {
this.check_lifetime_params(old_scope, &generics.params);
let scope = Scope::TraitRefBoundary { s: this.scope }; let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |_, this| { this.with(scope, |this| {
intravisit::walk_item(this, item); intravisit::walk_item(this, item);
}); });
}); });
@ -873,10 +862,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: true, allow_late_bound: true,
}; };
self.with(scope, |old_scope, this| { self.with(scope, |this| {
// a bare fn has no bounds, so everything // a bare fn has no bounds, so everything
// contained within is scoped within its binder. // contained within is scoped within its binder.
this.check_lifetime_params(old_scope, &c.generic_params);
intravisit::walk_ty(this, ty); intravisit::walk_ty(this, ty);
}); });
self.missing_named_lifetime_spots.pop(); 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, _) => { hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
debug!(?bounds, ?lifetime, "TraitObject"); debug!(?bounds, ?lifetime, "TraitObject");
let scope = Scope::TraitRefBoundary { s: self.scope }; let scope = Scope::TraitRefBoundary { s: self.scope };
self.with(scope, |_, this| { self.with(scope, |this| {
for bound in bounds { for bound in bounds {
this.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None); 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(), lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
s: self.scope, 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) => { hir::TyKind::OpaqueDef(item_id, lifetimes) => {
// Resolve the lifetimes in the bounds to the lifetime defs in the generics. // 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 // Elided lifetimes are not allowed in non-return
// position impl Trait // position impl Trait
let scope = Scope::TraitRefBoundary { s: self.scope }; 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 }; let scope = Scope::Elision { elide: Elide::Forbid, s: this.scope };
this.with(scope, |_, this| { this.with(scope, |this| {
intravisit::walk_item(this, opaque_ty); 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 { if let Some(elision_region) = elision {
let scope = let scope =
Scope::Elision { elide: Elide::Exact(elision_region), s: self.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 { let scope = Scope::Binder {
hir_id: ty.hir_id, hir_id: ty.hir_id,
lifetimes, lifetimes,
@ -1062,10 +1050,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: false, allow_late_bound: false,
}; };
this.with(scope, |_old_scope, this| { this.with(scope, |this| {
this.visit_generics(generics); this.visit_generics(generics);
let scope = Scope::TraitRefBoundary { s: this.scope }; let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |_, this| { this.with(scope, |this| {
for bound in bounds { for bound in bounds {
this.visit_param_bound(bound); this.visit_param_bound(bound);
} }
@ -1082,9 +1070,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: false, allow_late_bound: false,
}; };
self.with(scope, |_old_scope, this| { self.with(scope, |this| {
let scope = Scope::TraitRefBoundary { s: this.scope }; let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |_, this| { this.with(scope, |this| {
this.visit_generics(generics); this.visit_generics(generics);
for bound in bounds { for bound in bounds {
this.visit_param_bound(bound); this.visit_param_bound(bound);
@ -1141,10 +1129,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: false, allow_late_bound: false,
}; };
self.with(scope, |old_scope, this| { self.with(scope, |this| {
this.check_lifetime_params(old_scope, &generics.params);
let scope = Scope::TraitRefBoundary { s: this.scope }; let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |_, this| { this.with(scope, |this| {
this.visit_generics(generics); this.visit_generics(generics);
for bound in bounds { for bound in bounds {
this.visit_param_bound(bound); this.visit_param_bound(bound);
@ -1210,10 +1197,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: true, allow_late_bound: true,
}; };
self.with(scope, |old_scope, this| { self.with(scope, |this| {
this.check_lifetime_params(old_scope, &generics.params);
let scope = Scope::TraitRefBoundary { s: this.scope }; let scope = Scope::TraitRefBoundary { s: this.scope };
this.with(scope, |_, this| { this.with(scope, |this| {
this.visit_generics(generics); this.visit_generics(generics);
this.visit_ty(ty); 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>) { fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
let scope = Scope::TraitRefBoundary { s: self.scope }; let scope = Scope::TraitRefBoundary { s: self.scope };
self.with(scope, |_, this| { self.with(scope, |this| {
for param in generics.params { for param in generics.params {
match param.kind { match param.kind {
GenericParamKind::Lifetime { .. } => {} GenericParamKind::Lifetime { .. } => {}
@ -1354,8 +1340,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: true, allow_late_bound: true,
}; };
this.with(scope, |old_scope, this| { this.with(scope, |this| {
this.check_lifetime_params(old_scope, &bound_generic_params);
this.visit_ty(&bounded_ty); this.visit_ty(&bounded_ty);
walk_list!(this, visit_param_bound, bounds); walk_list!(this, visit_param_bound, bounds);
}) })
@ -1427,7 +1412,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type, scope_type,
allow_late_bound: true, allow_late_bound: true,
}; };
self.with(scope, |_, this| { self.with(scope, |this| {
intravisit::walk_param_bound(this, bound); intravisit::walk_param_bound(this, bound);
}); });
} }
@ -1479,8 +1464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
scope_type, scope_type,
allow_late_bound: true, allow_late_bound: true,
}; };
self.with(scope, |old_scope, this| { self.with(scope, |this| {
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params); walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
this.visit_trait_ref(&trait_ref.trait_ref); 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<Ident>,
}
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<Ident> {
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>( fn compute_object_lifetime_defaults<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
item: &hir::Item<'_>, item: &hir::Item<'_>,
@ -1774,10 +1610,9 @@ fn object_lifetime_defaults_for_item<'tcx>(
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F) fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
where where
F: for<'b> FnOnce(ScopeRef<'_>, &mut LifetimeContext<'b, 'tcx>), F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
{ {
let LifetimeContext { tcx, map, .. } = self; 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 xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults);
let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots); let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots);
let mut this = LifetimeContext { let mut this = LifetimeContext {
@ -1785,16 +1620,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
map, map,
scope: &wrap_scope, scope: &wrap_scope,
trait_definition_only: self.trait_definition_only, trait_definition_only: self.trait_definition_only,
labels_in_fn,
xcrate_object_lifetime_defaults, xcrate_object_lifetime_defaults,
missing_named_lifetime_spots, missing_named_lifetime_spots,
}; };
let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope)); let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
{ {
let _enter = span.enter(); 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.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
self.missing_named_lifetime_spots = this.missing_named_lifetime_spots; self.missing_named_lifetime_spots = this.missing_named_lifetime_spots;
} }
@ -1891,10 +1724,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
scope_type: BinderScopeType::Normal, scope_type: BinderScopeType::Normal,
allow_late_bound: true, allow_late_bound: true,
}; };
self.with(scope, move |old_scope, this| { self.with(scope, walk);
this.check_lifetime_params(old_scope, &generics.params);
walk(this);
});
} }
fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 { 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) => { GenericArg::Type(ty) => {
if let Some(&lt) = object_lifetime_defaults.get(i) { if let Some(&lt) = object_lifetime_defaults.get(i) {
let scope = Scope::ObjectLifetimeDefault { lifetime: lt, s: self.scope }; 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 { } else {
self.visit_ty(ty); self.visit_ty(ty);
} }
@ -2222,15 +2052,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
type_def_id, type_def_id,
binding.ident, binding.ident,
); );
self.with(scope, |_, this| { self.with(scope, |this| {
let scope = Scope::Supertrait { let scope = Scope::Supertrait {
lifetimes: lifetimes.unwrap_or_default(), lifetimes: lifetimes.unwrap_or_default(),
s: this.scope, s: this.scope,
}; };
this.with(scope, |_, this| this.visit_assoc_type_binding(binding)); this.with(scope, |this| this.visit_assoc_type_binding(binding));
}); });
} else { } 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)), elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)),
s: self.scope, s: self.scope,
}; };
self.with(arg_scope, |_, this| { self.with(arg_scope, |this| {
for input in inputs { for input in inputs {
this.visit_ty(input); this.visit_ty(input);
} }
@ -2466,7 +2296,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
visitor.visit_ty(&inputs[0]); visitor.visit_ty(&inputs[0]);
if let Set1::One(lifetime) = visitor.lifetime { if let Set1::One(lifetime) = visitor.lifetime {
let scope = Scope::Elision { elide: Elide::Exact(lifetime), s: self.scope }; 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; return;
} }
} }
@ -2517,7 +2347,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
debug!(?elide); debug!(?elide);
let scope = Scope::Elision { elide, s: self.scope }; 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> { struct GatherLifetimes<'a> {
map: &'a NamedRegionMap, map: &'a NamedRegionMap,
@ -2789,101 +2619,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth)); 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(&param),
);
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(&param.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(&param),
);
return;
}
old_scope = s;
}
}
}
}
#[tracing::instrument(level = "debug", skip(self))] #[tracing::instrument(level = "debug", skip(self))]
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) { fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
debug!( debug!(

View file

@ -1,5 +1,5 @@
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
//~^ ERROR E0263 //~^ ERROR E0403
} }
fn main() {} fn main() {}

View file

@ -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 --> $DIR/E0263.rs:1:16
| |
LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) { LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
| -- ^^ declared twice | -- ^^ already used
| | | |
| previous declaration here | first use of `'a`
error: aborting due to previous error 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`.

View file

@ -102,7 +102,7 @@ fn label_break_match(c: u8, xe: u8, ye: i8) {
0 => break 'a 0, 0 => break 'a 0,
v if { if v % 2 == 0 { break 'a 1; }; v % 3 == 0 } => { x += 1; }, v if { if v % 2 == 0 { break 'a 1; }; v % 3 == 0 } => { x += 1; },
v if { 'b: { break 'b v == 5; } } => { x = 41; }, v if { 'b: { break 'b v == 5; } } => { x = 41; },
_ => 'b: { //~ WARNING `'b` shadows a label _ => 'b: {
break 'b (); break 'b ();
}, },
} }
@ -128,8 +128,8 @@ fn label_break_macro() {
0 0
}; };
assert_eq!(x, 0); assert_eq!(x, 0);
let x: u8 = 'a: { //~ WARNING `'a` shadows a label let x: u8 = 'a: {
'b: { //~ WARNING `'b` shadows a label 'b: {
if true { if true {
mac1!('a, 1); mac1!('a, 1);
} }

View file

@ -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

View file

@ -20,14 +20,11 @@ fn lbv_macro_test_hygiene_respected() {
macro_rules! mac3 { macro_rules! mac3 {
($val:expr) => { ($val:expr) => {
'a: { 'a: {
//~^ WARNING `'a` shadows a label
//~| WARNING `'a` shadows a label
//~| WARNING `'a` shadows a label
$val $val
} }
}; };
} }
let x: u8 = mac3!('b: { //~ WARNING `'b` shadows a label let x: u8 = mac3!('b: {
if true { if true {
break 'a 3; //~ ERROR undeclared label `'a` [E0426] break 'a 3; //~ ERROR undeclared label `'a` [E0426]
} }

View file

@ -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) = 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` 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: { LL | let x: u8 = mac3!('b: {
| -- a label with a similar name is reachable | -- a label with a similar name is reachable
@ -22,68 +22,11 @@ LL | break 'a 3;
| help: try using similarly named label: `'b` | help: try using similarly named label: `'b`
error[E0426]: use of undeclared label `'a` 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); LL | let x: u8 = mac3!(break 'a 4);
| ^^ undeclared label `'a` | ^^ undeclared label `'a`
warning: label name `'a` shadows a label name that is already in scope error: aborting due to 3 previous errors
--> $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
For more information about this error, try `rustc --explain E0426`. For more information about this error, try `rustc --explain E0426`.

View file

@ -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 error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
--> $DIR/shadowing.rs:18:14 --> $DIR/shadowing.rs:18:14
| |
@ -14,22 +30,6 @@ LL | impl<T> NoShadowT<T> for Option<T> {
LL | type Bar<T> = i32; LL | type Bar<T> = i32;
| ^ already used | ^ 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 error: aborting due to 4 previous errors
Some errors have detailed explanations: E0403, E0496. Some errors have detailed explanations: E0403, E0496.

View file

@ -5,12 +5,12 @@
#[rustc_macro_transparency = "semitransparent"] #[rustc_macro_transparency = "semitransparent"]
macro m($a:lifetime) { 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"] #[rustc_macro_transparency = "transparent"]
macro n($a:lifetime) { 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); m!('a);

View file

@ -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 --> $DIR/duplicate_lifetimes.rs:8:14
| |
LL | fn g<$a, 'a>() {} LL | fn g<$a, 'a>() {}
| ^^ declared twice | ^^ already used
... ...
LL | m!('a); LL | m!('a);
| ------ | ------
| | | | | |
| | previous declaration here | | first use of `'a`
| in this macro invocation | in this macro invocation
| |
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info) = 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 --> $DIR/duplicate_lifetimes.rs:13:14
| |
LL | fn h<$a, 'a>() {} LL | fn h<$a, 'a>() {}
| ^^ declared twice | ^^ already used
... ...
LL | n!('a); LL | n!('a);
| ------ | ------
| | | | | |
| | previous declaration here | | first use of `'a`
| in this macro invocation | in this macro invocation
| |
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info) = 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 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`.

View file

@ -13,38 +13,28 @@
macro_rules! loop_x { macro_rules! loop_x {
($e: expr) => { ($e: expr) => {
// $e shouldn't be able to interact with this 'x // $e shouldn't be able to interact with this 'x
'x: loop { $e } 'x: loop {
//~^ WARNING shadows a label name that is already in scope $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
}
} }
macro_rules! while_true { macro_rules! while_true {
($e: expr) => { ($e: expr) => {
// $e shouldn't be able to interact with this 'x // $e shouldn't be able to interact with this 'x
'x: while 1 + 1 == 2 { $e } 'x: while 1 + 1 == 2 {
//~^ WARNING shadows a label name that is already in scope $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
}
} }
macro_rules! run_once { macro_rules! run_once {
($e: expr) => { ($e: expr) => {
// ditto // ditto
'x: for _ in 0..1 { $e } 'x: for _ in 0..1 {
//~^ WARNING shadows a label name that is already in scope $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
}
} }
pub fn main() { pub fn main() {
@ -62,8 +52,6 @@ pub fn main() {
let k: isize = { let k: isize = {
'x: for _ in 0..1 { '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 // ditto
loop_x!(break 'x); loop_x!(break 'x);
i += 1; i += 1;
@ -74,10 +62,6 @@ pub fn main() {
let l: isize = { let l: isize = {
'x: for _ in 0..1 { '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 // ditto
while_true!(break 'x); while_true!(break 'x);
i += 1; i += 1;
@ -88,12 +72,6 @@ pub fn main() {
let n: isize = { let n: isize = {
'x: for _ in 0..1 { '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 // ditto
run_once!(continue 'x); run_once!(continue 'x);
i += 1; i += 1;

View file

@ -1,334 +0,0 @@
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: 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
|
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

View file

@ -10,38 +10,28 @@
macro_rules! loop_x { macro_rules! loop_x {
($e: expr) => { ($e: expr) => {
// $e shouldn't be able to interact with this 'x // $e shouldn't be able to interact with this 'x
'x: loop { $e } 'x: loop {
//~^ WARNING shadows a label name that is already in scope $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
}
} }
macro_rules! run_once { macro_rules! run_once {
($e: expr) => { ($e: expr) => {
// ditto // ditto
'x: for _ in 0..1 { $e } 'x: for _ in 0..1 {
//~^ WARNING shadows a label name that is already in scope $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
}
} }
macro_rules! while_x { macro_rules! while_x {
($e: expr) => { ($e: expr) => {
// ditto // ditto
'x: while 1 + 1 == 2 { $e } 'x: while 1 + 1 == 2 {
//~^ WARNING shadows a label name that is already in scope $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
}
} }
pub fn main() { pub fn main() {
@ -52,32 +42,17 @@ pub fn main() {
} }
'x: loop { 'x: loop {
//~^ WARNING shadows a label name that is already in scope
//~| WARNING shadows a label name that is already in scope
// ditto // ditto
loop_x!(break 'x); loop_x!(break 'x);
panic!("break doesn't act hygienically inside infinite loop"); panic!("break doesn't act hygienically inside infinite loop");
} }
'x: while 1 + 1 == 2 { '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); while_x!(break 'x);
panic!("break doesn't act hygienically inside infinite while loop"); panic!("break doesn't act hygienically inside infinite while loop");
} }
'x: for _ in 0..1 { '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 // ditto
run_once!(continue 'x); run_once!(continue 'x);
panic!("continue doesn't act hygienically inside for loop"); panic!("continue doesn't act hygienically inside for loop");

View file

@ -1,334 +0,0 @@
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 | // 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
|
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: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
|
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

View file

@ -1,3 +1,12 @@
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 warning: unused label
--> $DIR/unused_labels.rs:11:5 --> $DIR/unused_labels.rs:11:5
| |
@ -52,14 +61,5 @@ warning: unused label
LL | 'unused_block_label: { 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: 9 warnings emitted

View file

@ -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::<i32> { 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::<i32> { 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();
}

View file

@ -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::<i32> { 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::<i32> { 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

View file

@ -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::<i32> { 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::<i32> { 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();
}

View file

@ -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::<i32> { 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::<i32> { 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

View file

@ -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();
}

View file

@ -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

View file

@ -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<dyn for <'a> 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<dyn for <'b> Fn(&'b ())>;
//~^ WARN lifetime name `'b` shadows a label name that is already in scope
break 'b;
}
}
pub fn main() {
foo();
}

View file

@ -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<dyn for <'a> 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<dyn for <'b> Fn(&'b ())>;
| ^^ label `'b` already in scope
warning: 2 warnings emitted

View file

@ -18,7 +18,7 @@ macro_rules! br {
} }
macro_rules! br2 { macro_rules! br2 {
($b:lifetime) => { ($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. break $b; // this $b should refer to the outer loop.
} }
} }

View file

@ -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

View file

@ -1,5 +1,6 @@
struct Foo<'a, 'a> { //~ ERROR lifetime name `'a` declared twice struct Foo<'a, 'a> {
x: &'a isize //~^ ERROR the name `'a` is already used for a generic parameter
x: &'a isize,
} }
fn main() {} fn main() {}

View file

@ -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 --> $DIR/regions-name-duplicated.rs:1:16
| |
LL | struct Foo<'a, 'a> { LL | struct Foo<'a, 'a> {
| -- ^^ declared twice | -- ^^ already used
| | | |
| previous declaration here | first use of `'a`
error: aborting due to previous error 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`.