@@ -11,6 +11,10 @@ use crate::{path_names_to_string, BindingError, Finalize, LexicalScopeBinding};
11
11
use crate :: { Module , ModuleOrUniformRoot , NameBinding , ParentScope , PathResult } ;
12
12
use crate :: { ResolutionError , Resolver , Segment , UseError } ;
13
13
14
+ use diagnostics:: {
15
+ original_label, original_lifetime, original_lifetime_param, shadower_label, shadower_lifetime,
16
+ } ;
17
+
14
18
use rustc_ast:: ptr:: P ;
15
19
use rustc_ast:: visit:: { self , AssocCtxt , FnCtxt , FnKind , Visitor } ;
16
20
use rustc_ast:: * ;
@@ -163,6 +167,23 @@ impl RibKind<'_> {
163
167
AssocItemRibKind | ItemRibKind ( _) | ForwardGenericParamBanRibKind => true ,
164
168
}
165
169
}
170
+
171
+ /// This rib forbids referring to labels defined in upwards ribs.
172
+ fn is_label_barrier ( self ) -> bool {
173
+ match self {
174
+ NormalRibKind | MacroDefinition ( ..) => false ,
175
+
176
+ AssocItemRibKind
177
+ | ClosureOrAsyncRibKind
178
+ | FnItemRibKind
179
+ | ItemRibKind ( ..)
180
+ | ConstantItemRibKind ( ..)
181
+ | ModuleRibKind ( ..)
182
+ | ForwardGenericParamBanRibKind
183
+ | ConstParamTyRibKind
184
+ | InlineAsmSymRibKind => true ,
185
+ }
186
+ }
166
187
}
167
188
168
189
/// A single local scope.
@@ -684,7 +705,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
684
705
// Create a value rib for the function.
685
706
self . with_rib ( ValueNS , rib_kind, |this| {
686
707
// Create a label rib for the function.
687
- this. with_label_rib ( rib_kind , |this| {
708
+ this. with_label_rib ( FnItemRibKind , |this| {
688
709
let async_node_id = fn_kind. header ( ) . and_then ( |h| h. asyncness . opt_return_id ( ) ) ;
689
710
690
711
if let FnKind :: Fn ( _, _, _, _, generics, _) = fn_kind {
@@ -1351,22 +1372,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1351
1372
let ribs = & self . label_ribs [ rib_index + 1 ..] ;
1352
1373
1353
1374
for rib in ribs {
1354
- match rib. kind {
1355
- NormalRibKind | MacroDefinition ( ..) => {
1356
- // Nothing to do. Continue.
1357
- }
1358
-
1359
- AssocItemRibKind
1360
- | ClosureOrAsyncRibKind
1361
- | FnItemRibKind
1362
- | ItemRibKind ( ..)
1363
- | ConstantItemRibKind ( ..)
1364
- | ModuleRibKind ( ..)
1365
- | ForwardGenericParamBanRibKind
1366
- | ConstParamTyRibKind
1367
- | InlineAsmSymRibKind => {
1368
- return false ;
1369
- }
1375
+ if rib. kind . is_label_barrier ( ) {
1376
+ return false ;
1370
1377
}
1371
1378
}
1372
1379
@@ -1644,6 +1651,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1644
1651
let mut function_value_rib = Rib :: new ( kind) ;
1645
1652
let mut function_lifetime_rib = LifetimeRib :: new ( lifetime_kind) ;
1646
1653
let mut seen_bindings = FxHashMap :: default ( ) ;
1654
+ let mut seen_lifetimes = FxHashMap :: default ( ) ;
1647
1655
1648
1656
// We also can't shadow bindings from the parent item
1649
1657
if let AssocItemRibKind = kind {
@@ -1659,20 +1667,52 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1659
1667
add_bindings_for_ns ( TypeNS ) ;
1660
1668
}
1661
1669
1670
+ // Forbid shadowing lifetime bindings
1671
+ for rib in self . lifetime_ribs . iter ( ) . rev ( ) {
1672
+ seen_lifetimes. extend (
1673
+ rib. bindings . iter ( ) . map ( |( ident, _) | ( * ident, original_lifetime ( ident. span ) ) ) ,
1674
+ ) ;
1675
+ if let LifetimeRibKind :: Item = rib. kind {
1676
+ break ;
1677
+ }
1678
+ }
1679
+ for rib in self . label_ribs . iter ( ) . rev ( ) {
1680
+ if rib. kind . is_label_barrier ( ) {
1681
+ break ;
1682
+ }
1683
+ seen_lifetimes
1684
+ . extend ( rib. bindings . iter ( ) . map ( |( ident, _) | ( * ident, original_label ( ident. span ) ) ) ) ;
1685
+ }
1686
+
1662
1687
for param in params {
1663
1688
let ident = param. ident . normalize_to_macros_2_0 ( ) ;
1664
1689
debug ! ( "with_generic_param_rib: {}" , param. id) ;
1665
1690
1666
- match seen_bindings. entry ( ident) {
1667
- Entry :: Occupied ( entry) => {
1668
- let span = * entry. get ( ) ;
1669
- let err = ResolutionError :: NameAlreadyUsedInParameterList ( ident. name , span) ;
1670
- if !matches ! ( param. kind, GenericParamKind :: Lifetime ) {
1671
- self . report_error ( param. ident . span , err) ;
1691
+ if let GenericParamKind :: Lifetime = param. kind {
1692
+ match seen_lifetimes. entry ( ident) {
1693
+ Entry :: Occupied ( entry) => {
1694
+ let original = * entry. get ( ) ;
1695
+ diagnostics:: signal_shadowing_problem (
1696
+ self . r . session ,
1697
+ ident. name ,
1698
+ original,
1699
+ shadower_lifetime ( param. ident . span ) ,
1700
+ )
1701
+ }
1702
+ Entry :: Vacant ( entry) => {
1703
+ entry. insert ( original_lifetime_param ( param. ident . span ) ) ;
1672
1704
}
1673
1705
}
1674
- Entry :: Vacant ( entry) => {
1675
- entry. insert ( param. ident . span ) ;
1706
+ } else {
1707
+ match seen_bindings. entry ( ident) {
1708
+ Entry :: Occupied ( entry) => {
1709
+ let span = * entry. get ( ) ;
1710
+ let err = ResolutionError :: NameAlreadyUsedInParameterList ( ident. name , span) ;
1711
+ self . report_error ( param. ident . span , err) ;
1712
+ }
1713
+ Entry :: Vacant ( entry) => {
1714
+ entry. insert ( param. ident . span ) ;
1715
+ }
1676
1716
}
1677
1717
}
1678
1718
@@ -2852,8 +2892,35 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
2852
2892
if label. ident . as_str ( ) . as_bytes ( ) [ 1 ] != b'_' {
2853
2893
self . diagnostic_metadata . unused_labels . insert ( id, label. ident . span ) ;
2854
2894
}
2895
+
2896
+ // Forbid shadowing lifetime bindings
2897
+ let ident = label. ident . normalize_to_macro_rules ( ) ;
2898
+ for rib in self . lifetime_ribs . iter ( ) . rev ( ) {
2899
+ if let Some ( ( orig_ident, _) ) = rib. bindings . get_key_value ( & ident) {
2900
+ diagnostics:: signal_shadowing_problem (
2901
+ self . r . session ,
2902
+ label. ident . name ,
2903
+ original_lifetime ( orig_ident. span ) ,
2904
+ shadower_label ( label. ident . span ) ,
2905
+ )
2906
+ }
2907
+ }
2908
+ for rib in self . label_ribs . iter_mut ( ) . rev ( ) {
2909
+ if let Some ( ( orig_ident, _) ) = rib. bindings . get_key_value ( & ident) {
2910
+ diagnostics:: signal_shadowing_problem (
2911
+ self . r . session ,
2912
+ label. ident . name ,
2913
+ original_label ( orig_ident. span ) ,
2914
+ shadower_label ( label. ident . span ) ,
2915
+ )
2916
+ }
2917
+ if rib. kind . is_label_barrier ( ) {
2918
+ rib. bindings . insert ( ident, id) ;
2919
+ break ;
2920
+ }
2921
+ }
2922
+
2855
2923
self . with_label_rib ( NormalRibKind , |this| {
2856
- let ident = label. ident . normalize_to_macro_rules ( ) ;
2857
2924
this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id) ;
2858
2925
f ( this) ;
2859
2926
} ) ;
0 commit comments