@@ -12,6 +12,10 @@ use crate::{path_names_to_string, BindingError, Finalize, LexicalScopeBinding};
12
12
use crate :: { Module , ModuleOrUniformRoot , NameBinding , ParentScope , PathResult } ;
13
13
use crate :: { ResolutionError , Resolver , Segment , UseError } ;
14
14
15
+ use diagnostics:: {
16
+ original_label, original_lifetime, original_lifetime_param, shadower_label, shadower_lifetime,
17
+ } ;
18
+
15
19
use rustc_ast:: ptr:: P ;
16
20
use rustc_ast:: visit:: { self , AssocCtxt , BoundKind , FnCtxt , FnKind , Visitor } ;
17
21
use rustc_ast:: * ;
@@ -172,6 +176,23 @@ impl RibKind<'_> {
172
176
AssocItemRibKind | ItemRibKind ( _) | ForwardGenericParamBanRibKind => true ,
173
177
}
174
178
}
179
+
180
+ /// This rib forbids referring to labels defined in upwards ribs.
181
+ fn is_label_barrier ( self ) -> bool {
182
+ match self {
183
+ NormalRibKind | MacroDefinition ( ..) => false ,
184
+
185
+ AssocItemRibKind
186
+ | ClosureOrAsyncRibKind
187
+ | FnItemRibKind
188
+ | ItemRibKind ( ..)
189
+ | ConstantItemRibKind ( ..)
190
+ | ModuleRibKind ( ..)
191
+ | ForwardGenericParamBanRibKind
192
+ | ConstParamTyRibKind
193
+ | InlineAsmSymRibKind => true ,
194
+ }
195
+ }
175
196
}
176
197
177
198
/// A single local scope.
@@ -732,7 +753,7 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
732
753
// Create a value rib for the function.
733
754
self . with_rib ( ValueNS , rib_kind, |this| {
734
755
// Create a label rib for the function.
735
- this. with_label_rib ( rib_kind , |this| {
756
+ this. with_label_rib ( FnItemRibKind , |this| {
736
757
let async_node_id = fn_kind. header ( ) . and_then ( |h| h. asyncness . opt_return_id ( ) ) ;
737
758
738
759
if let FnKind :: Fn ( _, _, _, _, generics, _) = fn_kind {
@@ -1585,22 +1606,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1585
1606
let ribs = & self . label_ribs [ rib_index + 1 ..] ;
1586
1607
1587
1608
for rib in ribs {
1588
- match rib. kind {
1589
- NormalRibKind | MacroDefinition ( ..) => {
1590
- // Nothing to do. Continue.
1591
- }
1592
-
1593
- AssocItemRibKind
1594
- | ClosureOrAsyncRibKind
1595
- | FnItemRibKind
1596
- | ItemRibKind ( ..)
1597
- | ConstantItemRibKind ( ..)
1598
- | ModuleRibKind ( ..)
1599
- | ForwardGenericParamBanRibKind
1600
- | ConstParamTyRibKind
1601
- | InlineAsmSymRibKind => {
1602
- return false ;
1603
- }
1609
+ if rib. kind . is_label_barrier ( ) {
1610
+ return false ;
1604
1611
}
1605
1612
}
1606
1613
@@ -1895,6 +1902,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1895
1902
let mut function_value_rib = Rib :: new ( kind) ;
1896
1903
let mut function_lifetime_rib = LifetimeRib :: new ( lifetime_kind) ;
1897
1904
let mut seen_bindings = FxHashMap :: default ( ) ;
1905
+ let mut seen_lifetimes = FxHashMap :: default ( ) ;
1898
1906
1899
1907
// We also can't shadow bindings from the parent item
1900
1908
if let AssocItemRibKind = kind {
@@ -1910,20 +1918,52 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
1910
1918
add_bindings_for_ns ( TypeNS ) ;
1911
1919
}
1912
1920
1921
+ // Forbid shadowing lifetime bindings
1922
+ for rib in self . lifetime_ribs . iter ( ) . rev ( ) {
1923
+ seen_lifetimes. extend (
1924
+ rib. bindings . iter ( ) . map ( |( ident, _) | ( * ident, original_lifetime ( ident. span ) ) ) ,
1925
+ ) ;
1926
+ if let LifetimeRibKind :: Item = rib. kind {
1927
+ break ;
1928
+ }
1929
+ }
1930
+ for rib in self . label_ribs . iter ( ) . rev ( ) {
1931
+ if rib. kind . is_label_barrier ( ) {
1932
+ break ;
1933
+ }
1934
+ seen_lifetimes
1935
+ . extend ( rib. bindings . iter ( ) . map ( |( ident, _) | ( * ident, original_label ( ident. span ) ) ) ) ;
1936
+ }
1937
+
1913
1938
for param in params {
1914
1939
let ident = param. ident . normalize_to_macros_2_0 ( ) ;
1915
1940
debug ! ( "with_generic_param_rib: {}" , param. id) ;
1916
1941
1917
- match seen_bindings. entry ( ident) {
1918
- Entry :: Occupied ( entry) => {
1919
- let span = * entry. get ( ) ;
1920
- let err = ResolutionError :: NameAlreadyUsedInParameterList ( ident. name , span) ;
1921
- if !matches ! ( param. kind, GenericParamKind :: Lifetime ) {
1922
- self . report_error ( param. ident . span , err) ;
1942
+ if let GenericParamKind :: Lifetime = param. kind {
1943
+ match seen_lifetimes. entry ( ident) {
1944
+ Entry :: Occupied ( entry) => {
1945
+ let original = * entry. get ( ) ;
1946
+ diagnostics:: signal_shadowing_problem (
1947
+ self . r . session ,
1948
+ ident. name ,
1949
+ original,
1950
+ shadower_lifetime ( param. ident . span ) ,
1951
+ )
1952
+ }
1953
+ Entry :: Vacant ( entry) => {
1954
+ entry. insert ( original_lifetime_param ( param. ident . span ) ) ;
1923
1955
}
1924
1956
}
1925
- Entry :: Vacant ( entry) => {
1926
- entry. insert ( param. ident . span ) ;
1957
+ } else {
1958
+ match seen_bindings. entry ( ident) {
1959
+ Entry :: Occupied ( entry) => {
1960
+ let span = * entry. get ( ) ;
1961
+ let err = ResolutionError :: NameAlreadyUsedInParameterList ( ident. name , span) ;
1962
+ self . report_error ( param. ident . span , err) ;
1963
+ }
1964
+ Entry :: Vacant ( entry) => {
1965
+ entry. insert ( param. ident . span ) ;
1966
+ }
1927
1967
}
1928
1968
}
1929
1969
@@ -3114,8 +3154,35 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
3114
3154
if label. ident . as_str ( ) . as_bytes ( ) [ 1 ] != b'_' {
3115
3155
self . diagnostic_metadata . unused_labels . insert ( id, label. ident . span ) ;
3116
3156
}
3157
+
3158
+ // Forbid shadowing lifetime bindings
3159
+ let ident = label. ident . normalize_to_macro_rules ( ) ;
3160
+ for rib in self . lifetime_ribs . iter ( ) . rev ( ) {
3161
+ if let Some ( ( orig_ident, _) ) = rib. bindings . get_key_value ( & ident) {
3162
+ diagnostics:: signal_shadowing_problem (
3163
+ self . r . session ,
3164
+ label. ident . name ,
3165
+ original_lifetime ( orig_ident. span ) ,
3166
+ shadower_label ( label. ident . span ) ,
3167
+ )
3168
+ }
3169
+ }
3170
+ for rib in self . label_ribs . iter_mut ( ) . rev ( ) {
3171
+ if let Some ( ( orig_ident, _) ) = rib. bindings . get_key_value ( & ident) {
3172
+ diagnostics:: signal_shadowing_problem (
3173
+ self . r . session ,
3174
+ label. ident . name ,
3175
+ original_label ( orig_ident. span ) ,
3176
+ shadower_label ( label. ident . span ) ,
3177
+ )
3178
+ }
3179
+ if rib. kind . is_label_barrier ( ) {
3180
+ rib. bindings . insert ( ident, id) ;
3181
+ break ;
3182
+ }
3183
+ }
3184
+
3117
3185
self . with_label_rib ( NormalRibKind , |this| {
3118
- let ident = label. ident . normalize_to_macro_rules ( ) ;
3119
3186
this. label_ribs . last_mut ( ) . unwrap ( ) . bindings . insert ( ident, id) ;
3120
3187
f ( this) ;
3121
3188
} ) ;
0 commit comments