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> {
|
fn lower_generic_param(&mut self, param: &GenericParam) -> hir::GenericParam<'hir> {
|
||||||
let (name, kind) = match param.kind {
|
let (name, kind) = match param.kind {
|
||||||
GenericParamKind::Lifetime => {
|
GenericParamKind::Lifetime => {
|
||||||
let param_name = if param.ident.name == kw::StaticLifetime
|
// AST resolution emitted an error on those parameters, so we lower them using
|
||||||
|| param.ident.name == kw::UnderscoreLifetime
|
// `ParamName::Error`.
|
||||||
{
|
let param_name =
|
||||||
ParamName::Error
|
if let Some(LifetimeRes::Error) = self.resolver.get_lifetime_res(param.id) {
|
||||||
} else {
|
ParamName::Error
|
||||||
let ident = self.lower_ident(param.ident);
|
} else {
|
||||||
ParamName::Plain(ident)
|
let ident = self.lower_ident(param.ident);
|
||||||
};
|
ParamName::Plain(ident)
|
||||||
|
};
|
||||||
let kind =
|
let kind =
|
||||||
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
|
hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit };
|
||||||
|
|
||||||
|
@ -1880,10 +1881,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let name = match name {
|
|
||||||
hir::ParamName::Plain(ident) => hir::ParamName::Plain(self.lower_ident(ident)),
|
|
||||||
name => name,
|
|
||||||
};
|
|
||||||
|
|
||||||
let hir_id = self.lower_node_id(param.id);
|
let hir_id = self.lower_node_id(param.id);
|
||||||
self.lower_attrs(hir_id, ¶m.attrs);
|
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.
|
A lifetime was declared more than once in the same scope.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0263
|
```compile_fail,E0403
|
||||||
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error!
|
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str, z: &'a str) { // error!
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
@ -172,6 +172,23 @@ impl RibKind<'_> {
|
||||||
AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true,
|
AssocItemRibKind | ItemRibKind(_) | ForwardGenericParamBanRibKind => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This rib forbids referring to labels defined in upwards ribs.
|
||||||
|
fn is_label_barrier(self) -> bool {
|
||||||
|
match self {
|
||||||
|
NormalRibKind | MacroDefinition(..) => false,
|
||||||
|
|
||||||
|
AssocItemRibKind
|
||||||
|
| ClosureOrAsyncRibKind
|
||||||
|
| FnItemRibKind
|
||||||
|
| ItemRibKind(..)
|
||||||
|
| ConstantItemRibKind(..)
|
||||||
|
| ModuleRibKind(..)
|
||||||
|
| ForwardGenericParamBanRibKind
|
||||||
|
| ConstParamTyRibKind
|
||||||
|
| InlineAsmSymRibKind => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A single local scope.
|
/// A single local scope.
|
||||||
|
@ -732,7 +749,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
// Create a value rib for the function.
|
// Create a value rib for the function.
|
||||||
self.with_rib(ValueNS, rib_kind, |this| {
|
self.with_rib(ValueNS, rib_kind, |this| {
|
||||||
// Create a label rib for the function.
|
// Create a label rib for the function.
|
||||||
this.with_label_rib(rib_kind, |this| {
|
this.with_label_rib(FnItemRibKind, |this| {
|
||||||
let async_node_id = fn_kind.header().and_then(|h| h.asyncness.opt_return_id());
|
let async_node_id = fn_kind.header().and_then(|h| h.asyncness.opt_return_id());
|
||||||
|
|
||||||
if let FnKind::Fn(_, _, _, _, generics, _) = fn_kind {
|
if let FnKind::Fn(_, _, _, _, generics, _) = fn_kind {
|
||||||
|
@ -1531,13 +1548,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
|
|
||||||
/// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
|
/// Searches the current set of local scopes for labels. Returns the `NodeId` of the resolved
|
||||||
/// label and reports an error if the label is not found or is unreachable.
|
/// label and reports an error if the label is not found or is unreachable.
|
||||||
fn resolve_label(&mut self, mut label: Ident) -> Option<NodeId> {
|
fn resolve_label(&mut self, mut label: Ident) -> Result<(NodeId, Span), ResolutionError<'a>> {
|
||||||
let mut suggestion = None;
|
let mut suggestion = None;
|
||||||
|
|
||||||
// Preserve the original span so that errors contain "in this macro invocation"
|
|
||||||
// information.
|
|
||||||
let original_span = label.span;
|
|
||||||
|
|
||||||
for i in (0..self.label_ribs.len()).rev() {
|
for i in (0..self.label_ribs.len()).rev() {
|
||||||
let rib = &self.label_ribs[i];
|
let rib = &self.label_ribs[i];
|
||||||
|
|
||||||
|
@ -1553,18 +1566,13 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
if let Some((ident, id)) = rib.bindings.get_key_value(&ident) {
|
if let Some((ident, id)) = rib.bindings.get_key_value(&ident) {
|
||||||
let definition_span = ident.span;
|
let definition_span = ident.span;
|
||||||
return if self.is_label_valid_from_rib(i) {
|
return if self.is_label_valid_from_rib(i) {
|
||||||
Some(*id)
|
Ok((*id, definition_span))
|
||||||
} else {
|
} else {
|
||||||
self.report_error(
|
Err(ResolutionError::UnreachableLabel {
|
||||||
original_span,
|
name: label.name,
|
||||||
ResolutionError::UnreachableLabel {
|
definition_span,
|
||||||
name: label.name,
|
suggestion,
|
||||||
definition_span,
|
})
|
||||||
suggestion,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
None
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1573,11 +1581,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label));
|
suggestion = suggestion.or_else(|| self.suggestion_for_label_in_rib(i, label));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.report_error(
|
Err(ResolutionError::UndeclaredLabel { name: label.name, suggestion })
|
||||||
original_span,
|
|
||||||
ResolutionError::UndeclaredLabel { name: label.name, suggestion },
|
|
||||||
);
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determine whether or not a label from the `rib_index`th label rib is reachable.
|
/// Determine whether or not a label from the `rib_index`th label rib is reachable.
|
||||||
|
@ -1585,22 +1589,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
let ribs = &self.label_ribs[rib_index + 1..];
|
let ribs = &self.label_ribs[rib_index + 1..];
|
||||||
|
|
||||||
for rib in ribs {
|
for rib in ribs {
|
||||||
match rib.kind {
|
if rib.kind.is_label_barrier() {
|
||||||
NormalRibKind | MacroDefinition(..) => {
|
return false;
|
||||||
// Nothing to do. Continue.
|
|
||||||
}
|
|
||||||
|
|
||||||
AssocItemRibKind
|
|
||||||
| ClosureOrAsyncRibKind
|
|
||||||
| FnItemRibKind
|
|
||||||
| ItemRibKind(..)
|
|
||||||
| ConstantItemRibKind(..)
|
|
||||||
| ModuleRibKind(..)
|
|
||||||
| ForwardGenericParamBanRibKind
|
|
||||||
| ConstParamTyRibKind
|
|
||||||
| InlineAsmSymRibKind => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1895,6 +1885,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
let mut function_value_rib = Rib::new(kind);
|
let mut function_value_rib = Rib::new(kind);
|
||||||
let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
|
let mut function_lifetime_rib = LifetimeRib::new(lifetime_kind);
|
||||||
let mut seen_bindings = FxHashMap::default();
|
let mut seen_bindings = FxHashMap::default();
|
||||||
|
// Store all seen lifetimes names from outer scopes.
|
||||||
|
let mut seen_lifetimes = FxHashSet::default();
|
||||||
|
|
||||||
// We also can't shadow bindings from the parent item
|
// We also can't shadow bindings from the parent item
|
||||||
if let AssocItemRibKind = kind {
|
if let AssocItemRibKind = kind {
|
||||||
|
@ -1910,16 +1902,36 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
add_bindings_for_ns(TypeNS);
|
add_bindings_for_ns(TypeNS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forbid shadowing lifetime bindings
|
||||||
|
for rib in self.lifetime_ribs.iter().rev() {
|
||||||
|
seen_lifetimes.extend(rib.bindings.iter().map(|(ident, _)| *ident));
|
||||||
|
if let LifetimeRibKind::Item = rib.kind {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for param in params {
|
for param in params {
|
||||||
let ident = param.ident.normalize_to_macros_2_0();
|
let ident = param.ident.normalize_to_macros_2_0();
|
||||||
debug!("with_generic_param_rib: {}", param.id);
|
debug!("with_generic_param_rib: {}", param.id);
|
||||||
|
|
||||||
|
if let GenericParamKind::Lifetime = param.kind
|
||||||
|
&& let Some(&original) = seen_lifetimes.get(&ident)
|
||||||
|
{
|
||||||
|
diagnostics::signal_lifetime_shadowing(self.r.session, original, param.ident);
|
||||||
|
// Record lifetime res, so lowering knows there is something fishy.
|
||||||
|
self.record_lifetime_res(param.id, LifetimeRes::Error);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
match seen_bindings.entry(ident) {
|
match seen_bindings.entry(ident) {
|
||||||
Entry::Occupied(entry) => {
|
Entry::Occupied(entry) => {
|
||||||
let span = *entry.get();
|
let span = *entry.get();
|
||||||
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
|
let err = ResolutionError::NameAlreadyUsedInParameterList(ident.name, span);
|
||||||
if !matches!(param.kind, GenericParamKind::Lifetime) {
|
self.report_error(param.ident.span, err);
|
||||||
self.report_error(param.ident.span, err);
|
if let GenericParamKind::Lifetime = param.kind {
|
||||||
|
// Record lifetime res, so lowering knows there is something fishy.
|
||||||
|
self.record_lifetime_res(param.id, LifetimeRes::Error);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Entry::Vacant(entry) => {
|
Entry::Vacant(entry) => {
|
||||||
|
@ -1936,6 +1948,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
)
|
)
|
||||||
.span_label(param.ident.span, "`'_` is a reserved lifetime name")
|
.span_label(param.ident.span, "`'_` is a reserved lifetime name")
|
||||||
.emit();
|
.emit();
|
||||||
|
// Record lifetime res, so lowering knows there is something fishy.
|
||||||
|
self.record_lifetime_res(param.id, LifetimeRes::Error);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1949,6 +1963,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
)
|
)
|
||||||
.span_label(param.ident.span, "'static is a reserved lifetime name")
|
.span_label(param.ident.span, "'static is a reserved lifetime name")
|
||||||
.emit();
|
.emit();
|
||||||
|
// Record lifetime res, so lowering knows there is something fishy.
|
||||||
|
self.record_lifetime_res(param.id, LifetimeRes::Error);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3114,6 +3130,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
if label.ident.as_str().as_bytes()[1] != b'_' {
|
if label.ident.as_str().as_bytes()[1] != b'_' {
|
||||||
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
|
self.diagnostic_metadata.unused_labels.insert(id, label.ident.span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Ok((_, orig_span)) = self.resolve_label(label.ident) {
|
||||||
|
diagnostics::signal_label_shadowing(self.r.session, orig_span, label.ident)
|
||||||
|
}
|
||||||
|
|
||||||
self.with_label_rib(NormalRibKind, |this| {
|
self.with_label_rib(NormalRibKind, |this| {
|
||||||
let ident = label.ident.normalize_to_macro_rules();
|
let ident = label.ident.normalize_to_macro_rules();
|
||||||
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
|
this.label_ribs.last_mut().unwrap().bindings.insert(ident, id);
|
||||||
|
@ -3219,10 +3240,15 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||||
}
|
}
|
||||||
|
|
||||||
ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
|
ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
|
||||||
if let Some(node_id) = self.resolve_label(label.ident) {
|
match self.resolve_label(label.ident) {
|
||||||
// Since this res is a label, it is never read.
|
Ok((node_id, _)) => {
|
||||||
self.r.label_res_map.insert(expr.id, node_id);
|
// Since this res is a label, it is never read.
|
||||||
self.diagnostic_metadata.unused_labels.remove(&node_id);
|
self.r.label_res_map.insert(expr.id, node_id);
|
||||||
|
self.diagnostic_metadata.unused_labels.remove(&node_id);
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
self.report_error(label.ident.span, error);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// visit `break` argument if any
|
// visit `break` argument if any
|
||||||
|
|
|
@ -25,6 +25,7 @@ use rustc_hir::def_id::{DefId, CRATE_DEF_ID, LOCAL_CRATE};
|
||||||
use rustc_hir::PrimTy;
|
use rustc_hir::PrimTy;
|
||||||
use rustc_session::lint;
|
use rustc_session::lint;
|
||||||
use rustc_session::parse::feature_err;
|
use rustc_session::parse::feature_err;
|
||||||
|
use rustc_session::Session;
|
||||||
use rustc_span::edition::Edition;
|
use rustc_span::edition::Edition;
|
||||||
use rustc_span::hygiene::MacroKind;
|
use rustc_span::hygiene::MacroKind;
|
||||||
use rustc_span::lev_distance::find_best_match_for_name;
|
use rustc_span::lev_distance::find_best_match_for_name;
|
||||||
|
@ -2036,6 +2037,34 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Report lifetime/lifetime shadowing as an error.
|
||||||
|
pub fn signal_lifetime_shadowing(sess: &Session, orig: Ident, shadower: Ident) {
|
||||||
|
let mut err = struct_span_err!(
|
||||||
|
sess,
|
||||||
|
shadower.span,
|
||||||
|
E0496,
|
||||||
|
"lifetime name `{}` shadows a lifetime name that is already in scope",
|
||||||
|
orig.name,
|
||||||
|
);
|
||||||
|
err.span_label(orig.span, "first declared here");
|
||||||
|
err.span_label(shadower.span, format!("lifetime `{}` already in scope", orig.name));
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Shadowing involving a label is only a warning for historical reasons.
|
||||||
|
//FIXME: make this a proper lint.
|
||||||
|
pub fn signal_label_shadowing(sess: &Session, orig: Span, shadower: Ident) {
|
||||||
|
let name = shadower.name;
|
||||||
|
let shadower = shadower.span;
|
||||||
|
let mut err = sess.struct_span_warn(
|
||||||
|
shadower,
|
||||||
|
&format!("label name `{}` shadows a label name that is already in scope", name),
|
||||||
|
);
|
||||||
|
err.span_label(orig, "first declared here");
|
||||||
|
err.span_label(shadower, format!("label `{}` already in scope", name));
|
||||||
|
err.emit();
|
||||||
|
}
|
||||||
|
|
||||||
impl<'tcx> LifetimeContext<'_, 'tcx> {
|
impl<'tcx> LifetimeContext<'_, 'tcx> {
|
||||||
pub(crate) fn report_missing_lifetime_specifiers(
|
pub(crate) fn report_missing_lifetime_specifiers(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -23,7 +23,7 @@ use rustc_middle::middle::resolve_lifetime::*;
|
||||||
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
|
use rustc_middle::ty::{self, DefIdTree, GenericParamDefKind, TyCtxt};
|
||||||
use rustc_middle::{bug, span_bug};
|
use rustc_middle::{bug, span_bug};
|
||||||
use rustc_span::def_id::DefId;
|
use rustc_span::def_id::DefId;
|
||||||
use rustc_span::symbol::{kw, sym, Ident, Symbol};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::Span;
|
use rustc_span::Span;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
|
@ -161,9 +161,6 @@ pub(crate) struct LifetimeContext<'a, 'tcx> {
|
||||||
/// we eventually need lifetimes resolve for trait items.
|
/// we eventually need lifetimes resolve for trait items.
|
||||||
trait_definition_only: bool,
|
trait_definition_only: bool,
|
||||||
|
|
||||||
/// List of labels in the function/method currently under analysis.
|
|
||||||
labels_in_fn: Vec<Ident>,
|
|
||||||
|
|
||||||
/// Cache for cross-crate per-definition object lifetime defaults.
|
/// Cache for cross-crate per-definition object lifetime defaults.
|
||||||
xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
|
xcrate_object_lifetime_defaults: DefIdMap<Vec<ObjectLifetimeDefault>>,
|
||||||
|
|
||||||
|
@ -434,7 +431,6 @@ fn do_resolve(
|
||||||
map: &mut named_region_map,
|
map: &mut named_region_map,
|
||||||
scope: ROOT_SCOPE,
|
scope: ROOT_SCOPE,
|
||||||
trait_definition_only,
|
trait_definition_only,
|
||||||
labels_in_fn: vec![],
|
|
||||||
xcrate_object_lifetime_defaults: Default::default(),
|
xcrate_object_lifetime_defaults: Default::default(),
|
||||||
missing_named_lifetime_spots: vec![],
|
missing_named_lifetime_spots: vec![],
|
||||||
};
|
};
|
||||||
|
@ -641,14 +637,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_nested_body(&mut self, body: hir::BodyId) {
|
fn visit_nested_body(&mut self, body: hir::BodyId) {
|
||||||
// Each body has their own set of labels, save labels.
|
|
||||||
let saved = take(&mut self.labels_in_fn);
|
|
||||||
let body = self.tcx.hir().body(body);
|
let body = self.tcx.hir().body(body);
|
||||||
extract_labels(self, body);
|
self.with(Scope::Body { id: body.id(), s: self.scope }, |this| {
|
||||||
self.with(Scope::Body { id: body.id(), s: self.scope }, |_, this| {
|
|
||||||
this.visit_body(body);
|
this.visit_body(body);
|
||||||
});
|
});
|
||||||
self.labels_in_fn = saved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_fn(
|
fn visit_fn(
|
||||||
|
@ -683,9 +675,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
};
|
};
|
||||||
self.with(scope, move |_old_scope, this| {
|
self.with(scope, move |this| intravisit::walk_fn(this, fk, fd, b, s, hir_id));
|
||||||
intravisit::walk_fn(this, fk, fd, b, s, hir_id)
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -720,7 +710,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
|
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => {
|
||||||
// No lifetime parameters, but implied 'static.
|
// No lifetime parameters, but implied 'static.
|
||||||
let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE };
|
let scope = Scope::Elision { elide: Elide::Exact(Region::Static), s: ROOT_SCOPE };
|
||||||
self.with(scope, |_, this| intravisit::walk_item(this, item));
|
self.with(scope, |this| intravisit::walk_item(this, item));
|
||||||
}
|
}
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => {
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy { .. }) => {
|
||||||
// Opaque types are visited when we visit the
|
// Opaque types are visited when we visit the
|
||||||
|
@ -807,10 +797,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
s: ROOT_SCOPE,
|
s: ROOT_SCOPE,
|
||||||
allow_late_bound: false,
|
allow_late_bound: false,
|
||||||
};
|
};
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |this| {
|
||||||
this.check_lifetime_params(old_scope, &generics.params);
|
|
||||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||||
this.with(scope, |_, this| {
|
this.with(scope, |this| {
|
||||||
intravisit::walk_item(this, item);
|
intravisit::walk_item(this, item);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -873,10 +862,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
};
|
};
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |this| {
|
||||||
// a bare fn has no bounds, so everything
|
// a bare fn has no bounds, so everything
|
||||||
// contained within is scoped within its binder.
|
// contained within is scoped within its binder.
|
||||||
this.check_lifetime_params(old_scope, &c.generic_params);
|
|
||||||
intravisit::walk_ty(this, ty);
|
intravisit::walk_ty(this, ty);
|
||||||
});
|
});
|
||||||
self.missing_named_lifetime_spots.pop();
|
self.missing_named_lifetime_spots.pop();
|
||||||
|
@ -884,7 +872,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
|
hir::TyKind::TraitObject(bounds, ref lifetime, _) => {
|
||||||
debug!(?bounds, ?lifetime, "TraitObject");
|
debug!(?bounds, ?lifetime, "TraitObject");
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
self.with(scope, |_, this| {
|
self.with(scope, |this| {
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
this.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
|
this.visit_poly_trait_ref(bound, hir::TraitBoundModifier::None);
|
||||||
}
|
}
|
||||||
|
@ -923,7 +911,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
|
lifetime: self.map.defs.get(&lifetime_ref.hir_id).cloned(),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
};
|
};
|
||||||
self.with(scope, |_, this| this.visit_ty(&mt.ty));
|
self.with(scope, |this| this.visit_ty(&mt.ty));
|
||||||
}
|
}
|
||||||
hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
hir::TyKind::OpaqueDef(item_id, lifetimes) => {
|
||||||
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
// Resolve the lifetimes in the bounds to the lifetime defs in the generics.
|
||||||
|
@ -944,9 +932,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
// Elided lifetimes are not allowed in non-return
|
// Elided lifetimes are not allowed in non-return
|
||||||
// position impl Trait
|
// position impl Trait
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
self.with(scope, |_, this| {
|
self.with(scope, |this| {
|
||||||
let scope = Scope::Elision { elide: Elide::Forbid, s: this.scope };
|
let scope = Scope::Elision { elide: Elide::Forbid, s: this.scope };
|
||||||
this.with(scope, |_, this| {
|
this.with(scope, |this| {
|
||||||
intravisit::walk_item(this, opaque_ty);
|
intravisit::walk_item(this, opaque_ty);
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1052,7 +1040,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
if let Some(elision_region) = elision {
|
if let Some(elision_region) = elision {
|
||||||
let scope =
|
let scope =
|
||||||
Scope::Elision { elide: Elide::Exact(elision_region), s: self.scope };
|
Scope::Elision { elide: Elide::Exact(elision_region), s: self.scope };
|
||||||
self.with(scope, |_old_scope, this| {
|
self.with(scope, |this| {
|
||||||
let scope = Scope::Binder {
|
let scope = Scope::Binder {
|
||||||
hir_id: ty.hir_id,
|
hir_id: ty.hir_id,
|
||||||
lifetimes,
|
lifetimes,
|
||||||
|
@ -1062,10 +1050,10 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: false,
|
allow_late_bound: false,
|
||||||
};
|
};
|
||||||
this.with(scope, |_old_scope, this| {
|
this.with(scope, |this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||||
this.with(scope, |_, this| {
|
this.with(scope, |this| {
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
this.visit_param_bound(bound);
|
this.visit_param_bound(bound);
|
||||||
}
|
}
|
||||||
|
@ -1082,9 +1070,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: false,
|
allow_late_bound: false,
|
||||||
};
|
};
|
||||||
self.with(scope, |_old_scope, this| {
|
self.with(scope, |this| {
|
||||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||||
this.with(scope, |_, this| {
|
this.with(scope, |this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
this.visit_param_bound(bound);
|
this.visit_param_bound(bound);
|
||||||
|
@ -1141,10 +1129,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: false,
|
allow_late_bound: false,
|
||||||
};
|
};
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |this| {
|
||||||
this.check_lifetime_params(old_scope, &generics.params);
|
|
||||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||||
this.with(scope, |_, this| {
|
this.with(scope, |this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
for bound in bounds {
|
for bound in bounds {
|
||||||
this.visit_param_bound(bound);
|
this.visit_param_bound(bound);
|
||||||
|
@ -1210,10 +1197,9 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
};
|
};
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |this| {
|
||||||
this.check_lifetime_params(old_scope, &generics.params);
|
|
||||||
let scope = Scope::TraitRefBoundary { s: this.scope };
|
let scope = Scope::TraitRefBoundary { s: this.scope };
|
||||||
this.with(scope, |_, this| {
|
this.with(scope, |this| {
|
||||||
this.visit_generics(generics);
|
this.visit_generics(generics);
|
||||||
this.visit_ty(ty);
|
this.visit_ty(ty);
|
||||||
})
|
})
|
||||||
|
@ -1300,7 +1286,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
|
|
||||||
fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
|
fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) {
|
||||||
let scope = Scope::TraitRefBoundary { s: self.scope };
|
let scope = Scope::TraitRefBoundary { s: self.scope };
|
||||||
self.with(scope, |_, this| {
|
self.with(scope, |this| {
|
||||||
for param in generics.params {
|
for param in generics.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamKind::Lifetime { .. } => {}
|
GenericParamKind::Lifetime { .. } => {}
|
||||||
|
@ -1354,8 +1340,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
};
|
};
|
||||||
this.with(scope, |old_scope, this| {
|
this.with(scope, |this| {
|
||||||
this.check_lifetime_params(old_scope, &bound_generic_params);
|
|
||||||
this.visit_ty(&bounded_ty);
|
this.visit_ty(&bounded_ty);
|
||||||
walk_list!(this, visit_param_bound, bounds);
|
walk_list!(this, visit_param_bound, bounds);
|
||||||
})
|
})
|
||||||
|
@ -1427,7 +1412,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type,
|
scope_type,
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
};
|
};
|
||||||
self.with(scope, |_, this| {
|
self.with(scope, |this| {
|
||||||
intravisit::walk_param_bound(this, bound);
|
intravisit::walk_param_bound(this, bound);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1479,8 +1464,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
scope_type,
|
scope_type,
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
};
|
};
|
||||||
self.with(scope, |old_scope, this| {
|
self.with(scope, |this| {
|
||||||
this.check_lifetime_params(old_scope, &trait_ref.bound_generic_params);
|
|
||||||
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
walk_list!(this, visit_generic_param, trait_ref.bound_generic_params);
|
||||||
this.visit_trait_ref(&trait_ref.trait_ref);
|
this.visit_trait_ref(&trait_ref.trait_ref);
|
||||||
});
|
});
|
||||||
|
@ -1491,154 +1475,6 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, PartialEq)]
|
|
||||||
enum ShadowKind {
|
|
||||||
Label,
|
|
||||||
Lifetime,
|
|
||||||
}
|
|
||||||
struct Original {
|
|
||||||
kind: ShadowKind,
|
|
||||||
span: Span,
|
|
||||||
}
|
|
||||||
struct Shadower {
|
|
||||||
kind: ShadowKind,
|
|
||||||
span: Span,
|
|
||||||
}
|
|
||||||
|
|
||||||
fn original_label(span: Span) -> Original {
|
|
||||||
Original { kind: ShadowKind::Label, span }
|
|
||||||
}
|
|
||||||
fn shadower_label(span: Span) -> Shadower {
|
|
||||||
Shadower { kind: ShadowKind::Label, span }
|
|
||||||
}
|
|
||||||
fn original_lifetime(span: Span) -> Original {
|
|
||||||
Original { kind: ShadowKind::Lifetime, span }
|
|
||||||
}
|
|
||||||
fn shadower_lifetime(param: &hir::GenericParam<'_>) -> Shadower {
|
|
||||||
Shadower { kind: ShadowKind::Lifetime, span: param.span }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ShadowKind {
|
|
||||||
fn desc(&self) -> &'static str {
|
|
||||||
match *self {
|
|
||||||
ShadowKind::Label => "label",
|
|
||||||
ShadowKind::Lifetime => "lifetime",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn signal_shadowing_problem(tcx: TyCtxt<'_>, name: Symbol, orig: Original, shadower: Shadower) {
|
|
||||||
let mut err = if let (ShadowKind::Lifetime, ShadowKind::Lifetime) = (orig.kind, shadower.kind) {
|
|
||||||
// lifetime/lifetime shadowing is an error
|
|
||||||
struct_span_err!(
|
|
||||||
tcx.sess,
|
|
||||||
shadower.span,
|
|
||||||
E0496,
|
|
||||||
"{} name `{}` shadows a \
|
|
||||||
{} name that is already in scope",
|
|
||||||
shadower.kind.desc(),
|
|
||||||
name,
|
|
||||||
orig.kind.desc()
|
|
||||||
)
|
|
||||||
.forget_guarantee()
|
|
||||||
} else {
|
|
||||||
// shadowing involving a label is only a warning, due to issues with
|
|
||||||
// labels and lifetimes not being macro-hygienic.
|
|
||||||
tcx.sess.struct_span_warn(
|
|
||||||
shadower.span,
|
|
||||||
&format!(
|
|
||||||
"{} name `{}` shadows a \
|
|
||||||
{} name that is already in scope",
|
|
||||||
shadower.kind.desc(),
|
|
||||||
name,
|
|
||||||
orig.kind.desc()
|
|
||||||
),
|
|
||||||
)
|
|
||||||
};
|
|
||||||
err.span_label(orig.span, "first declared here");
|
|
||||||
err.span_label(shadower.span, format!("{} `{}` already in scope", orig.kind.desc(), name));
|
|
||||||
err.emit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adds all labels in `b` to `ctxt.labels_in_fn`, signalling a warning
|
|
||||||
// if one of the label shadows a lifetime or another label.
|
|
||||||
fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
|
|
||||||
struct GatherLabels<'a, 'tcx> {
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
scope: ScopeRef<'a>,
|
|
||||||
labels_in_fn: &'a mut Vec<Ident>,
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut gather =
|
|
||||||
GatherLabels { tcx: ctxt.tcx, scope: ctxt.scope, labels_in_fn: &mut ctxt.labels_in_fn };
|
|
||||||
gather.visit_body(body);
|
|
||||||
|
|
||||||
impl<'v, 'a, 'tcx> Visitor<'v> for GatherLabels<'a, 'tcx> {
|
|
||||||
fn visit_expr(&mut self, ex: &hir::Expr<'_>) {
|
|
||||||
if let Some(label) = expression_label(ex) {
|
|
||||||
for prior_label in &self.labels_in_fn[..] {
|
|
||||||
// FIXME (#24278): non-hygienic comparison
|
|
||||||
if label.name == prior_label.name {
|
|
||||||
signal_shadowing_problem(
|
|
||||||
self.tcx,
|
|
||||||
label.name,
|
|
||||||
original_label(prior_label.span),
|
|
||||||
shadower_label(label.span),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
check_if_label_shadows_lifetime(self.tcx, self.scope, label);
|
|
||||||
|
|
||||||
self.labels_in_fn.push(label);
|
|
||||||
}
|
|
||||||
intravisit::walk_expr(self, ex)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn expression_label(ex: &hir::Expr<'_>) -> Option<Ident> {
|
|
||||||
match ex.kind {
|
|
||||||
hir::ExprKind::Loop(_, Some(label), ..) => Some(label.ident),
|
|
||||||
hir::ExprKind::Block(_, Some(label)) => Some(label.ident),
|
|
||||||
_ => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_if_label_shadows_lifetime(tcx: TyCtxt<'_>, mut scope: ScopeRef<'_>, label: Ident) {
|
|
||||||
loop {
|
|
||||||
match *scope {
|
|
||||||
Scope::Body { s, .. }
|
|
||||||
| Scope::Elision { s, .. }
|
|
||||||
| Scope::ObjectLifetimeDefault { s, .. }
|
|
||||||
| Scope::Supertrait { s, .. }
|
|
||||||
| Scope::TraitRefBoundary { s, .. } => {
|
|
||||||
scope = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope::Root => {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Scope::Binder { ref lifetimes, s, .. } => {
|
|
||||||
// FIXME (#24278): non-hygienic comparison
|
|
||||||
if let Some(def) =
|
|
||||||
lifetimes.get(&hir::ParamName::Plain(label.normalize_to_macros_2_0()))
|
|
||||||
{
|
|
||||||
signal_shadowing_problem(
|
|
||||||
tcx,
|
|
||||||
label.name,
|
|
||||||
original_lifetime(tcx.def_span(def.id().unwrap().expect_local())),
|
|
||||||
shadower_label(label.span),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
scope = s;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn compute_object_lifetime_defaults<'tcx>(
|
fn compute_object_lifetime_defaults<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
item: &hir::Item<'_>,
|
item: &hir::Item<'_>,
|
||||||
|
@ -1774,10 +1610,9 @@ fn object_lifetime_defaults_for_item<'tcx>(
|
||||||
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
|
fn with<F>(&mut self, wrap_scope: Scope<'_>, f: F)
|
||||||
where
|
where
|
||||||
F: for<'b> FnOnce(ScopeRef<'_>, &mut LifetimeContext<'b, 'tcx>),
|
F: for<'b> FnOnce(&mut LifetimeContext<'b, 'tcx>),
|
||||||
{
|
{
|
||||||
let LifetimeContext { tcx, map, .. } = self;
|
let LifetimeContext { tcx, map, .. } = self;
|
||||||
let labels_in_fn = take(&mut self.labels_in_fn);
|
|
||||||
let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults);
|
let xcrate_object_lifetime_defaults = take(&mut self.xcrate_object_lifetime_defaults);
|
||||||
let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots);
|
let missing_named_lifetime_spots = take(&mut self.missing_named_lifetime_spots);
|
||||||
let mut this = LifetimeContext {
|
let mut this = LifetimeContext {
|
||||||
|
@ -1785,16 +1620,14 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
map,
|
map,
|
||||||
scope: &wrap_scope,
|
scope: &wrap_scope,
|
||||||
trait_definition_only: self.trait_definition_only,
|
trait_definition_only: self.trait_definition_only,
|
||||||
labels_in_fn,
|
|
||||||
xcrate_object_lifetime_defaults,
|
xcrate_object_lifetime_defaults,
|
||||||
missing_named_lifetime_spots,
|
missing_named_lifetime_spots,
|
||||||
};
|
};
|
||||||
let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
|
let span = tracing::debug_span!("scope", scope = ?TruncatedScopeDebug(&this.scope));
|
||||||
{
|
{
|
||||||
let _enter = span.enter();
|
let _enter = span.enter();
|
||||||
f(self.scope, &mut this);
|
f(&mut this);
|
||||||
}
|
}
|
||||||
self.labels_in_fn = this.labels_in_fn;
|
|
||||||
self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
|
self.xcrate_object_lifetime_defaults = this.xcrate_object_lifetime_defaults;
|
||||||
self.missing_named_lifetime_spots = this.missing_named_lifetime_spots;
|
self.missing_named_lifetime_spots = this.missing_named_lifetime_spots;
|
||||||
}
|
}
|
||||||
|
@ -1891,10 +1724,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
scope_type: BinderScopeType::Normal,
|
scope_type: BinderScopeType::Normal,
|
||||||
allow_late_bound: true,
|
allow_late_bound: true,
|
||||||
};
|
};
|
||||||
self.with(scope, move |old_scope, this| {
|
self.with(scope, walk);
|
||||||
this.check_lifetime_params(old_scope, &generics.params);
|
|
||||||
walk(this);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 {
|
fn next_early_index_helper(&self, only_opaque_type_parent: bool) -> u32 {
|
||||||
|
@ -2165,7 +1995,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
GenericArg::Type(ty) => {
|
GenericArg::Type(ty) => {
|
||||||
if let Some(<) = object_lifetime_defaults.get(i) {
|
if let Some(<) = object_lifetime_defaults.get(i) {
|
||||||
let scope = Scope::ObjectLifetimeDefault { lifetime: lt, s: self.scope };
|
let scope = Scope::ObjectLifetimeDefault { lifetime: lt, s: self.scope };
|
||||||
self.with(scope, |_, this| this.visit_ty(ty));
|
self.with(scope, |this| this.visit_ty(ty));
|
||||||
} else {
|
} else {
|
||||||
self.visit_ty(ty);
|
self.visit_ty(ty);
|
||||||
}
|
}
|
||||||
|
@ -2222,15 +2052,15 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
type_def_id,
|
type_def_id,
|
||||||
binding.ident,
|
binding.ident,
|
||||||
);
|
);
|
||||||
self.with(scope, |_, this| {
|
self.with(scope, |this| {
|
||||||
let scope = Scope::Supertrait {
|
let scope = Scope::Supertrait {
|
||||||
lifetimes: lifetimes.unwrap_or_default(),
|
lifetimes: lifetimes.unwrap_or_default(),
|
||||||
s: this.scope,
|
s: this.scope,
|
||||||
};
|
};
|
||||||
this.with(scope, |_, this| this.visit_assoc_type_binding(binding));
|
this.with(scope, |this| this.visit_assoc_type_binding(binding));
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.with(scope, |_, this| this.visit_assoc_type_binding(binding));
|
self.with(scope, |this| this.visit_assoc_type_binding(binding));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2346,7 +2176,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)),
|
elide: Elide::FreshLateAnon(named_late_bound_vars, Cell::new(0)),
|
||||||
s: self.scope,
|
s: self.scope,
|
||||||
};
|
};
|
||||||
self.with(arg_scope, |_, this| {
|
self.with(arg_scope, |this| {
|
||||||
for input in inputs {
|
for input in inputs {
|
||||||
this.visit_ty(input);
|
this.visit_ty(input);
|
||||||
}
|
}
|
||||||
|
@ -2466,7 +2296,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
visitor.visit_ty(&inputs[0]);
|
visitor.visit_ty(&inputs[0]);
|
||||||
if let Set1::One(lifetime) = visitor.lifetime {
|
if let Set1::One(lifetime) = visitor.lifetime {
|
||||||
let scope = Scope::Elision { elide: Elide::Exact(lifetime), s: self.scope };
|
let scope = Scope::Elision { elide: Elide::Exact(lifetime), s: self.scope };
|
||||||
self.with(scope, |_, this| this.visit_ty(output));
|
self.with(scope, |this| this.visit_ty(output));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2517,7 +2347,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
debug!(?elide);
|
debug!(?elide);
|
||||||
|
|
||||||
let scope = Scope::Elision { elide, s: self.scope };
|
let scope = Scope::Elision { elide, s: self.scope };
|
||||||
self.with(scope, |_, this| this.visit_ty(output));
|
self.with(scope, |this| this.visit_ty(output));
|
||||||
|
|
||||||
struct GatherLifetimes<'a> {
|
struct GatherLifetimes<'a> {
|
||||||
map: &'a NamedRegionMap,
|
map: &'a NamedRegionMap,
|
||||||
|
@ -2789,101 +2619,6 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
|
||||||
self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
|
self.insert_lifetime(lifetime_ref, lifetime.shifted(late_depth));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_lifetime_params(
|
|
||||||
&mut self,
|
|
||||||
old_scope: ScopeRef<'_>,
|
|
||||||
params: &'tcx [hir::GenericParam<'tcx>],
|
|
||||||
) {
|
|
||||||
let lifetimes: Vec<_> = params
|
|
||||||
.iter()
|
|
||||||
.filter_map(|param| match param.kind {
|
|
||||||
GenericParamKind::Lifetime { .. } => {
|
|
||||||
Some((param, param.name.normalize_to_macros_2_0()))
|
|
||||||
}
|
|
||||||
_ => None,
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
for (i, (lifetime_i, lifetime_i_name)) in lifetimes.iter().enumerate() {
|
|
||||||
if let hir::ParamName::Plain(_) = lifetime_i_name {
|
|
||||||
let name = lifetime_i_name.ident().name;
|
|
||||||
if name == kw::UnderscoreLifetime || name == kw::StaticLifetime {
|
|
||||||
self.tcx.sess.delay_span_bug(
|
|
||||||
lifetime_i.span,
|
|
||||||
&format!("invalid lifetime parameter name: `{}`", lifetime_i.name.ident()),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is a hard error to shadow a lifetime within the same scope.
|
|
||||||
for (lifetime_j, lifetime_j_name) in lifetimes.iter().skip(i + 1) {
|
|
||||||
if lifetime_i_name == lifetime_j_name {
|
|
||||||
struct_span_err!(
|
|
||||||
self.tcx.sess,
|
|
||||||
lifetime_j.span,
|
|
||||||
E0263,
|
|
||||||
"lifetime name `{}` declared twice in the same scope",
|
|
||||||
lifetime_j.name.ident()
|
|
||||||
)
|
|
||||||
.span_label(lifetime_j.span, "declared twice")
|
|
||||||
.span_label(lifetime_i.span, "previous declaration here")
|
|
||||||
.emit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// It is a soft error to shadow a lifetime within a parent scope.
|
|
||||||
self.check_lifetime_param_for_shadowing(old_scope, &lifetime_i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn check_lifetime_param_for_shadowing(
|
|
||||||
&self,
|
|
||||||
mut old_scope: ScopeRef<'_>,
|
|
||||||
param: &'tcx hir::GenericParam<'tcx>,
|
|
||||||
) {
|
|
||||||
for label in &self.labels_in_fn {
|
|
||||||
// FIXME (#24278): non-hygienic comparison
|
|
||||||
if param.name.ident().name == label.name {
|
|
||||||
signal_shadowing_problem(
|
|
||||||
self.tcx,
|
|
||||||
label.name,
|
|
||||||
original_label(label.span),
|
|
||||||
shadower_lifetime(¶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))]
|
#[tracing::instrument(level = "debug", skip(self))]
|
||||||
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
|
fn insert_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime, def: Region) {
|
||||||
debug!(
|
debug!(
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
|
fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
|
||||||
//~^ ERROR E0263
|
//~^ ERROR E0403
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0263]: lifetime name `'a` declared twice in the same scope
|
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
|
||||||
--> $DIR/E0263.rs:1:16
|
--> $DIR/E0263.rs:1:16
|
||||||
|
|
|
|
||||||
LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
|
LL | fn foo<'a, 'b, 'a>(x: &'a str, y: &'b str) {
|
||||||
| -- ^^ declared twice
|
| -- ^^ already used
|
||||||
| |
|
| |
|
||||||
| previous declaration here
|
| first use of `'a`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0263`.
|
For more information about this error, try `rustc --explain E0403`.
|
||||||
|
|
|
@ -102,7 +102,7 @@ fn label_break_match(c: u8, xe: u8, ye: i8) {
|
||||||
0 => break 'a 0,
|
0 => break 'a 0,
|
||||||
v if { if v % 2 == 0 { break 'a 1; }; v % 3 == 0 } => { x += 1; },
|
v if { if v % 2 == 0 { break 'a 1; }; v % 3 == 0 } => { x += 1; },
|
||||||
v if { 'b: { break 'b v == 5; } } => { x = 41; },
|
v if { 'b: { break 'b v == 5; } } => { x = 41; },
|
||||||
_ => 'b: { //~ WARNING `'b` shadows a label
|
_ => 'b: {
|
||||||
break 'b ();
|
break 'b ();
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -128,8 +128,8 @@ fn label_break_macro() {
|
||||||
0
|
0
|
||||||
};
|
};
|
||||||
assert_eq!(x, 0);
|
assert_eq!(x, 0);
|
||||||
let x: u8 = 'a: { //~ WARNING `'a` shadows a label
|
let x: u8 = 'a: {
|
||||||
'b: { //~ WARNING `'b` shadows a label
|
'b: {
|
||||||
if true {
|
if true {
|
||||||
mac1!('a, 1);
|
mac1!('a, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
macro_rules! mac3 {
|
||||||
($val:expr) => {
|
($val:expr) => {
|
||||||
'a: {
|
'a: {
|
||||||
//~^ WARNING `'a` shadows a label
|
|
||||||
//~| WARNING `'a` shadows a label
|
|
||||||
//~| WARNING `'a` shadows a label
|
|
||||||
$val
|
$val
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
let x: u8 = mac3!('b: { //~ WARNING `'b` shadows a label
|
let x: u8 = mac3!('b: {
|
||||||
if true {
|
if true {
|
||||||
break 'a 3; //~ ERROR undeclared label `'a` [E0426]
|
break 'a 3; //~ ERROR undeclared label `'a` [E0426]
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ LL | mac2!(2);
|
||||||
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `mac2` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error[E0426]: use of undeclared label `'a`
|
error[E0426]: use of undeclared label `'a`
|
||||||
--> $DIR/label_break_value_invalid.rs:32:19
|
--> $DIR/label_break_value_invalid.rs:29:19
|
||||||
|
|
|
|
||||||
LL | let x: u8 = mac3!('b: {
|
LL | let x: u8 = mac3!('b: {
|
||||||
| -- a label with a similar name is reachable
|
| -- a label with a similar name is reachable
|
||||||
|
@ -22,68 +22,11 @@ LL | break 'a 3;
|
||||||
| help: try using similarly named label: `'b`
|
| help: try using similarly named label: `'b`
|
||||||
|
|
||||||
error[E0426]: use of undeclared label `'a`
|
error[E0426]: use of undeclared label `'a`
|
||||||
--> $DIR/label_break_value_invalid.rs:37:29
|
--> $DIR/label_break_value_invalid.rs:34:29
|
||||||
|
|
|
|
||||||
LL | let x: u8 = mac3!(break 'a 4);
|
LL | let x: u8 = mac3!(break 'a 4);
|
||||||
| ^^ undeclared label `'a`
|
| ^^ undeclared label `'a`
|
||||||
|
|
||||||
warning: label name `'a` shadows a label name that is already in scope
|
error: aborting due to 3 previous errors
|
||||||
--> $DIR/label_break_value_invalid.rs:22:13
|
|
||||||
|
|
|
||||||
LL | let x: u8 = 'a: {
|
|
||||||
| -- first declared here
|
|
||||||
...
|
|
||||||
LL | 'a: {
|
|
||||||
| ^^ label `'a` already in scope
|
|
||||||
...
|
|
||||||
LL | let x: u8 = mac3!('b: {
|
|
||||||
| _________________-
|
|
||||||
LL | | if true {
|
|
||||||
LL | | break 'a 3;
|
|
||||||
LL | | }
|
|
||||||
LL | | 0
|
|
||||||
LL | | });
|
|
||||||
| |______- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
warning: label name `'b` shadows a label name that is already in scope
|
|
||||||
--> $DIR/label_break_value_invalid.rs:30:23
|
|
||||||
|
|
|
||||||
LL | 'b: {
|
|
||||||
| -- first declared here
|
|
||||||
...
|
|
||||||
LL | let x: u8 = mac3!('b: {
|
|
||||||
| ^^ label `'b` already in scope
|
|
||||||
|
|
||||||
warning: label name `'a` shadows a label name that is already in scope
|
|
||||||
--> $DIR/label_break_value_invalid.rs:22:13
|
|
||||||
|
|
|
||||||
LL | let x: u8 = 'a: {
|
|
||||||
| -- first declared here
|
|
||||||
...
|
|
||||||
LL | 'a: {
|
|
||||||
| ^^ label `'a` already in scope
|
|
||||||
...
|
|
||||||
LL | let x: u8 = mac3!(break 'a 4);
|
|
||||||
| ----------------- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
warning: label name `'a` shadows a label name that is already in scope
|
|
||||||
--> $DIR/label_break_value_invalid.rs:22:13
|
|
||||||
|
|
|
||||||
LL | 'a: {
|
|
||||||
| ^^
|
|
||||||
| |
|
|
||||||
| first declared here
|
|
||||||
| label `'a` already in scope
|
|
||||||
...
|
|
||||||
LL | let x: u8 = mac3!(break 'a 4);
|
|
||||||
| ----------------- in this macro invocation
|
|
||||||
|
|
|
||||||
= note: this warning originates in the macro `mac3` (in Nightly builds, run with -Z macro-backtrace for more info)
|
|
||||||
|
|
||||||
error: aborting due to 3 previous errors; 4 warnings emitted
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0426`.
|
For more information about this error, try `rustc --explain E0426`.
|
||||||
|
|
|
@ -1,3 +1,19 @@
|
||||||
|
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
|
||||||
|
--> $DIR/shadowing.rs:4:14
|
||||||
|
|
|
||||||
|
LL | trait Shadow<'a> {
|
||||||
|
| -- first declared here
|
||||||
|
LL | type Bar<'a>;
|
||||||
|
| ^^ lifetime `'a` already in scope
|
||||||
|
|
||||||
|
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
|
||||||
|
--> $DIR/shadowing.rs:13:14
|
||||||
|
|
|
||||||
|
LL | impl<'a> NoShadow<'a> for &'a u32 {
|
||||||
|
| -- first declared here
|
||||||
|
LL | type Bar<'a> = i32;
|
||||||
|
| ^^ lifetime `'a` already in scope
|
||||||
|
|
||||||
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
|
error[E0403]: the name `T` is already used for a generic parameter in this item's generic parameters
|
||||||
--> $DIR/shadowing.rs:18:14
|
--> $DIR/shadowing.rs:18:14
|
||||||
|
|
|
|
||||||
|
@ -14,22 +30,6 @@ LL | impl<T> NoShadowT<T> for Option<T> {
|
||||||
LL | type Bar<T> = i32;
|
LL | type Bar<T> = i32;
|
||||||
| ^ already used
|
| ^ already used
|
||||||
|
|
||||||
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
|
|
||||||
--> $DIR/shadowing.rs:13:14
|
|
||||||
|
|
|
||||||
LL | impl<'a> NoShadow<'a> for &'a u32 {
|
|
||||||
| -- first declared here
|
|
||||||
LL | type Bar<'a> = i32;
|
|
||||||
| ^^ lifetime `'a` already in scope
|
|
||||||
|
|
||||||
error[E0496]: lifetime name `'a` shadows a lifetime name that is already in scope
|
|
||||||
--> $DIR/shadowing.rs:4:14
|
|
||||||
|
|
|
||||||
LL | trait Shadow<'a> {
|
|
||||||
| -- first declared here
|
|
||||||
LL | type Bar<'a>;
|
|
||||||
| ^^ lifetime `'a` already in scope
|
|
||||||
|
|
||||||
error: aborting due to 4 previous errors
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0403, E0496.
|
Some errors have detailed explanations: E0403, E0496.
|
||||||
|
|
|
@ -5,12 +5,12 @@
|
||||||
|
|
||||||
#[rustc_macro_transparency = "semitransparent"]
|
#[rustc_macro_transparency = "semitransparent"]
|
||||||
macro m($a:lifetime) {
|
macro m($a:lifetime) {
|
||||||
fn g<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice
|
fn g<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
#[rustc_macro_transparency = "transparent"]
|
#[rustc_macro_transparency = "transparent"]
|
||||||
macro n($a:lifetime) {
|
macro n($a:lifetime) {
|
||||||
fn h<$a, 'a>() {} //~ ERROR lifetime name `'a` declared twice
|
fn h<$a, 'a>() {} //~ ERROR the name `'a` is already used for a generic parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
m!('a);
|
m!('a);
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
error[E0263]: lifetime name `'a` declared twice in the same scope
|
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
|
||||||
--> $DIR/duplicate_lifetimes.rs:8:14
|
--> $DIR/duplicate_lifetimes.rs:8:14
|
||||||
|
|
|
|
||||||
LL | fn g<$a, 'a>() {}
|
LL | fn g<$a, 'a>() {}
|
||||||
| ^^ declared twice
|
| ^^ already used
|
||||||
...
|
...
|
||||||
LL | m!('a);
|
LL | m!('a);
|
||||||
| ------
|
| ------
|
||||||
| | |
|
| | |
|
||||||
| | previous declaration here
|
| | first use of `'a`
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error[E0263]: lifetime name `'a` declared twice in the same scope
|
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
|
||||||
--> $DIR/duplicate_lifetimes.rs:13:14
|
--> $DIR/duplicate_lifetimes.rs:13:14
|
||||||
|
|
|
|
||||||
LL | fn h<$a, 'a>() {}
|
LL | fn h<$a, 'a>() {}
|
||||||
| ^^ declared twice
|
| ^^ already used
|
||||||
...
|
...
|
||||||
LL | n!('a);
|
LL | n!('a);
|
||||||
| ------
|
| ------
|
||||||
| | |
|
| | |
|
||||||
| | previous declaration here
|
| | first use of `'a`
|
||||||
| in this macro invocation
|
| in this macro invocation
|
||||||
|
|
|
|
||||||
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `n` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0263`.
|
For more information about this error, try `rustc --explain E0403`.
|
||||||
|
|
|
@ -13,38 +13,28 @@
|
||||||
macro_rules! loop_x {
|
macro_rules! loop_x {
|
||||||
($e: expr) => {
|
($e: expr) => {
|
||||||
// $e shouldn't be able to interact with this 'x
|
// $e shouldn't be able to interact with this 'x
|
||||||
'x: loop { $e }
|
'x: loop {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
$e
|
||||||
//~| WARNING shadows a label name that is already in scope
|
}
|
||||||
//~| WARNING shadows a label name that is already in scope
|
};
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! while_true {
|
macro_rules! while_true {
|
||||||
($e: expr) => {
|
($e: expr) => {
|
||||||
// $e shouldn't be able to interact with this 'x
|
// $e shouldn't be able to interact with this 'x
|
||||||
'x: while 1 + 1 == 2 { $e }
|
'x: while 1 + 1 == 2 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
$e
|
||||||
//~| WARNING shadows a label name that is already in scope
|
}
|
||||||
//~| WARNING shadows a label name that is already in scope
|
};
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! run_once {
|
macro_rules! run_once {
|
||||||
($e: expr) => {
|
($e: expr) => {
|
||||||
// ditto
|
// ditto
|
||||||
'x: for _ in 0..1 { $e }
|
'x: for _ in 0..1 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
$e
|
||||||
//~| WARNING shadows a label name that is already in scope
|
}
|
||||||
//~| WARNING shadows a label name that is already in scope
|
};
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
@ -62,8 +52,6 @@ pub fn main() {
|
||||||
|
|
||||||
let k: isize = {
|
let k: isize = {
|
||||||
'x: for _ in 0..1 {
|
'x: for _ in 0..1 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
// ditto
|
// ditto
|
||||||
loop_x!(break 'x);
|
loop_x!(break 'x);
|
||||||
i += 1;
|
i += 1;
|
||||||
|
@ -74,10 +62,6 @@ pub fn main() {
|
||||||
|
|
||||||
let l: isize = {
|
let l: isize = {
|
||||||
'x: for _ in 0..1 {
|
'x: for _ in 0..1 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
// ditto
|
// ditto
|
||||||
while_true!(break 'x);
|
while_true!(break 'x);
|
||||||
i += 1;
|
i += 1;
|
||||||
|
@ -88,12 +72,6 @@ pub fn main() {
|
||||||
|
|
||||||
let n: isize = {
|
let n: isize = {
|
||||||
'x: for _ in 0..1 {
|
'x: for _ in 0..1 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
// ditto
|
// ditto
|
||||||
run_once!(continue 'x);
|
run_once!(continue 'x);
|
||||||
i += 1;
|
i += 1;
|
||||||
|
|
|
@ -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 {
|
macro_rules! loop_x {
|
||||||
($e: expr) => {
|
($e: expr) => {
|
||||||
// $e shouldn't be able to interact with this 'x
|
// $e shouldn't be able to interact with this 'x
|
||||||
'x: loop { $e }
|
'x: loop {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
$e
|
||||||
//~| WARNING shadows a label name that is already in scope
|
}
|
||||||
//~| WARNING shadows a label name that is already in scope
|
};
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! run_once {
|
macro_rules! run_once {
|
||||||
($e: expr) => {
|
($e: expr) => {
|
||||||
// ditto
|
// ditto
|
||||||
'x: for _ in 0..1 { $e }
|
'x: for _ in 0..1 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
$e
|
||||||
//~| WARNING shadows a label name that is already in scope
|
}
|
||||||
//~| WARNING shadows a label name that is already in scope
|
};
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! while_x {
|
macro_rules! while_x {
|
||||||
($e: expr) => {
|
($e: expr) => {
|
||||||
// ditto
|
// ditto
|
||||||
'x: while 1 + 1 == 2 { $e }
|
'x: while 1 + 1 == 2 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
$e
|
||||||
//~| WARNING shadows a label name that is already in scope
|
}
|
||||||
//~| WARNING shadows a label name that is already in scope
|
};
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() {
|
pub fn main() {
|
||||||
|
@ -52,32 +42,17 @@ pub fn main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
'x: loop {
|
'x: loop {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
|
|
||||||
// ditto
|
// ditto
|
||||||
loop_x!(break 'x);
|
loop_x!(break 'x);
|
||||||
panic!("break doesn't act hygienically inside infinite loop");
|
panic!("break doesn't act hygienically inside infinite loop");
|
||||||
}
|
}
|
||||||
|
|
||||||
'x: while 1 + 1 == 2 {
|
'x: while 1 + 1 == 2 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
|
|
||||||
while_x!(break 'x);
|
while_x!(break 'x);
|
||||||
panic!("break doesn't act hygienically inside infinite while loop");
|
panic!("break doesn't act hygienically inside infinite while loop");
|
||||||
}
|
}
|
||||||
|
|
||||||
'x: for _ in 0..1 {
|
'x: for _ in 0..1 {
|
||||||
//~^ WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
//~| WARNING shadows a label name that is already in scope
|
|
||||||
|
|
||||||
// ditto
|
// ditto
|
||||||
run_once!(continue 'x);
|
run_once!(continue 'x);
|
||||||
panic!("continue doesn't act hygienically inside for loop");
|
panic!("continue doesn't act hygienically inside for loop");
|
||||||
|
|
|
@ -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
|
warning: unused label
|
||||||
--> $DIR/unused_labels.rs:11:5
|
--> $DIR/unused_labels.rs:11:5
|
||||||
|
|
|
|
||||||
|
@ -52,14 +61,5 @@ warning: unused label
|
||||||
LL | 'unused_block_label: {
|
LL | 'unused_block_label: {
|
||||||
| ^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
warning: label name `'many_used_shadowed` shadows a label name that is already in scope
|
|
||||||
--> $DIR/unused_labels.rs:62:9
|
|
||||||
|
|
|
||||||
LL | 'many_used_shadowed: for _ in 0..10 {
|
|
||||||
| ------------------- first declared here
|
|
||||||
LL |
|
|
||||||
LL | 'many_used_shadowed: for _ in 0..10 {
|
|
||||||
| ^^^^^^^^^^^^^^^^^^^ label `'many_used_shadowed` already in scope
|
|
||||||
|
|
||||||
warning: 9 warnings emitted
|
warning: 9 warnings emitted
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
macro_rules! br2 {
|
||||||
($b:lifetime) => {
|
($b:lifetime) => {
|
||||||
'b: loop { //~ WARNING `'b` shadows a label name that is already in scope
|
'b: loop {
|
||||||
break $b; // this $b should refer to the outer loop.
|
break $b; // this $b should refer to the outer loop.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
struct Foo<'a, 'a> {
|
||||||
x: &'a isize
|
//~^ ERROR the name `'a` is already used for a generic parameter
|
||||||
|
x: &'a isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
error[E0263]: lifetime name `'a` declared twice in the same scope
|
error[E0403]: the name `'a` is already used for a generic parameter in this item's generic parameters
|
||||||
--> $DIR/regions-name-duplicated.rs:1:16
|
--> $DIR/regions-name-duplicated.rs:1:16
|
||||||
|
|
|
|
||||||
LL | struct Foo<'a, 'a> {
|
LL | struct Foo<'a, 'a> {
|
||||||
| -- ^^ declared twice
|
| -- ^^ already used
|
||||||
| |
|
| |
|
||||||
| previous declaration here
|
| first use of `'a`
|
||||||
|
|
||||||
error: aborting due to previous error
|
error: aborting due to previous error
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0263`.
|
For more information about this error, try `rustc --explain E0403`.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue