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:
commit
3a90bedb33
31 changed files with 223 additions and 1751 deletions
|
@ -1848,14 +1848,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 };
|
||||
|
||||
|
@ -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);
|
||||
self.lower_attrs(hir_id, ¶m.attrs);
|
||||
|
|
|
@ -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!
|
||||
}
|
||||
```
|
||||
|
|
|
@ -172,6 +172,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 +749,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 {
|
||||
|
@ -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
|
||||
/// 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;
|
||||
|
||||
// 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];
|
||||
|
||||
|
@ -1553,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,
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -1585,22 +1589,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 +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 from outer scopes.
|
||||
let mut seen_lifetimes = FxHashSet::default();
|
||||
|
||||
// We also can't shadow bindings from the parent item
|
||||
if let AssocItemRibKind = kind {
|
||||
|
@ -1910,16 +1902,36 @@ 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));
|
||||
if let LifetimeRibKind::Item = rib.kind {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for param in params {
|
||||
let ident = param.ident.normalize_to_macros_2_0();
|
||||
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) {
|
||||
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);
|
||||
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) => {
|
||||
|
@ -1936,6 +1948,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;
|
||||
}
|
||||
|
||||
|
@ -1949,6 +1963,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;
|
||||
}
|
||||
|
||||
|
@ -3114,6 +3130,11 @@ 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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -3219,10 +3240,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
|
||||
|
|
|
@ -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,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> {
|
||||
pub(crate) fn report_missing_lifetime_specifiers(
|
||||
&self,
|
||||
|
|
|
@ -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<Ident>,
|
||||
|
||||
/// Cache for cross-crate per-definition object lifetime defaults.
|
||||
xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
|
||||
|
||||
|
@ -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<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>(
|
||||
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<F>(&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!(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
|
||||
//~^ ERROR E0263
|
||||
//~^ ERROR E0403
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -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) {
|
||||
| -- ^^ declared twice
|
||||
| -- ^^ already used
|
||||
| |
|
||||
| previous declaration 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`.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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]
|
||||
}
|
||||
|
|
|
@ -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`.
|
||||
|
|
|
@ -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<T> NoShadowT<T> for Option<T> {
|
|||
LL | type Bar<T> = 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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>() {}
|
||||
| ^^ declared twice
|
||||
| ^^ already used
|
||||
...
|
||||
LL | m!('a);
|
||||
| ------
|
||||
| | |
|
||||
| | previous declaration 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>() {}
|
||||
| ^^ declared twice
|
||||
| ^^ already used
|
||||
...
|
||||
LL | n!('a);
|
||||
| ------
|
||||
| | |
|
||||
| | previous declaration 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`.
|
||||
|
|
|
@ -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() {
|
||||
|
@ -62,8 +52,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;
|
||||
|
@ -74,10 +62,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;
|
||||
|
@ -88,12 +72,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;
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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() {
|
||||
|
@ -52,32 +42,17 @@ 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);
|
||||
panic!("break doesn't act hygienically inside infinite loop");
|
||||
}
|
||||
|
||||
'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");
|
||||
}
|
||||
|
||||
'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);
|
||||
panic!("continue doesn't act hygienically inside for loop");
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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
|
||||
--> $DIR/unused_labels.rs:11:5
|
||||
|
|
||||
|
@ -52,14 +61,5 @@ warning: unused 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
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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
|
||||
|
|
@ -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.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
struct Foo<'a, 'a> { //~ ERROR lifetime name `'a` declared twice
|
||||
x: &'a isize
|
||||
struct Foo<'a, 'a> {
|
||||
//~^ ERROR the name `'a` is already used for a generic parameter
|
||||
x: &'a isize,
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
@ -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> {
|
||||
| -- ^^ declared twice
|
||||
| -- ^^ already used
|
||||
| |
|
||||
| previous declaration 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`.
|
||||
|
|
Loading…
Add table
Reference in a new issue