@@ -1689,7 +1689,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1689
1689
}
1690
1690
}
1691
1691
}
1692
- DefTyParam ( ..) | DefSelfTy ( _ ) => {
1692
+ DefTyParam ( ..) | DefSelfTy ( .. ) => {
1693
1693
for rib in ribs {
1694
1694
match rib. kind {
1695
1695
NormalRibKind | MethodRibKind | ClosureRibKind ( ..) => {
@@ -1797,63 +1797,57 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1797
1797
}
1798
1798
1799
1799
ItemDefaultImpl ( _, ref trait_ref) => {
1800
- self . with_optional_trait_ref ( Some ( trait_ref) , |_| { } ) ;
1800
+ self . with_optional_trait_ref ( Some ( trait_ref) , |_, _ | { } ) ;
1801
1801
}
1802
- ItemImpl ( _, _,
1802
+ ItemImpl ( _,
1803
+ _,
1803
1804
ref generics,
1804
- ref implemented_traits ,
1805
+ ref opt_trait_ref ,
1805
1806
ref self_type,
1806
1807
ref impl_items) => {
1807
1808
self . resolve_implementation ( generics,
1808
- implemented_traits ,
1809
+ opt_trait_ref ,
1809
1810
& * * self_type,
1811
+ item. id ,
1810
1812
& impl_items[ ..] ) ;
1811
1813
}
1812
1814
1813
1815
ItemTrait ( _, ref generics, ref bounds, ref trait_items) => {
1814
1816
self . check_if_primitive_type_name ( name, item. span ) ;
1815
1817
1816
- // Create a new rib for the self type.
1817
- let mut self_type_rib = Rib :: new ( ItemRibKind ) ;
1818
-
1819
- // plain insert (no renaming, types are not currently hygienic....)
1820
- let name = special_names:: type_self;
1821
- self_type_rib. bindings . insert ( name, DlDef ( DefSelfTy ( item. id ) ) ) ;
1822
- self . type_ribs . push ( self_type_rib) ;
1823
-
1824
- // Create a new rib for the trait-wide type parameters.
1825
- self . with_type_parameter_rib ( HasTypeParameters ( generics,
1826
- TypeSpace ,
1827
- NormalRibKind ) ,
1828
- |this| {
1829
- this. visit_generics ( generics) ;
1830
- visit:: walk_ty_param_bounds_helper ( this, bounds) ;
1831
-
1832
- for trait_item in trait_items {
1833
- // Create a new rib for the trait_item-specific type
1834
- // parameters.
1835
- //
1836
- // FIXME #4951: Do we need a node ID here?
1837
-
1838
- let type_parameters = match trait_item. node {
1839
- ast:: MethodTraitItem ( ref sig, _) => {
1840
- HasTypeParameters ( & sig. generics ,
1841
- FnSpace ,
1842
- MethodRibKind )
1843
- }
1844
- ast:: TypeTraitItem ( ..) => {
1845
- this. check_if_primitive_type_name ( trait_item. ident . name ,
1846
- trait_item. span ) ;
1847
- NoTypeParameters
1848
- }
1849
- } ;
1850
- this. with_type_parameter_rib ( type_parameters, |this| {
1851
- visit:: walk_trait_item ( this, trait_item)
1852
- } ) ;
1853
- }
1818
+ self . with_self_rib ( DefSelfTy ( Some ( local_def ( item. id ) ) , None ) , |this| {
1819
+ // Create a new rib for the trait-wide type parameters.
1820
+ this. with_type_parameter_rib ( HasTypeParameters ( generics,
1821
+ TypeSpace ,
1822
+ NormalRibKind ) ,
1823
+ |this| {
1824
+ this. visit_generics ( generics) ;
1825
+ visit:: walk_ty_param_bounds_helper ( this, bounds) ;
1826
+
1827
+ for trait_item in trait_items {
1828
+ // Create a new rib for the trait_item-specific type
1829
+ // parameters.
1830
+ //
1831
+ // FIXME #4951: Do we need a node ID here?
1832
+
1833
+ let type_parameters = match trait_item. node {
1834
+ ast:: MethodTraitItem ( ref sig, _) => {
1835
+ HasTypeParameters ( & sig. generics ,
1836
+ FnSpace ,
1837
+ MethodRibKind )
1838
+ }
1839
+ ast:: TypeTraitItem ( ..) => {
1840
+ this. check_if_primitive_type_name ( trait_item. ident . name ,
1841
+ trait_item. span ) ;
1842
+ NoTypeParameters
1843
+ }
1844
+ } ;
1845
+ this. with_type_parameter_rib ( type_parameters, |this| {
1846
+ visit:: walk_trait_item ( this, trait_item)
1847
+ } ) ;
1848
+ }
1849
+ } ) ;
1854
1850
} ) ;
1855
-
1856
- self . type_ribs . pop ( ) ;
1857
1851
}
1858
1852
1859
1853
ItemMod ( _) | ItemForeignMod ( _) => {
@@ -2030,8 +2024,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2030
2024
visit:: walk_generics ( self , generics) ;
2031
2025
}
2032
2026
2033
- fn with_current_self_type < T , F > ( & mut self , self_type : & Ty , f : F ) -> T where
2034
- F : FnOnce ( & mut Resolver ) -> T ,
2027
+ fn with_current_self_type < T , F > ( & mut self , self_type : & Ty , f : F ) -> T
2028
+ where F : FnOnce ( & mut Resolver ) -> T
2035
2029
{
2036
2030
// Handle nested impls (inside fn bodies)
2037
2031
let previous_value = replace ( & mut self . current_self_type , Some ( self_type. clone ( ) ) ) ;
@@ -2044,29 +2038,44 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2044
2038
opt_trait_ref : Option < & TraitRef > ,
2045
2039
f : F )
2046
2040
-> T
2047
- where F : FnOnce ( & mut Resolver ) -> T ,
2041
+ where F : FnOnce ( & mut Resolver , Option < DefId > ) -> T
2048
2042
{
2049
2043
let mut new_val = None ;
2044
+ let mut new_id = None ;
2050
2045
if let Some ( trait_ref) = opt_trait_ref {
2051
- match self . resolve_trait_reference ( trait_ref. ref_id , & trait_ref . path , 0 ) {
2052
- Ok ( path_res ) => {
2053
- self . record_def ( trait_ref . ref_id , path_res ) ;
2054
- new_val = Some ( ( path_res . base_def . def_id ( ) , trait_ref. clone ( ) ) ) ;
2055
- }
2056
- Err ( _ ) => { /* error was already reported */ }
2046
+ if let Ok ( path_res ) = self . resolve_trait_reference ( trait_ref. ref_id ,
2047
+ & trait_ref . path , 0 ) {
2048
+ assert ! ( path_res . depth == 0 ) ;
2049
+ self . record_def ( trait_ref. ref_id , path_res ) ;
2050
+ new_val = Some ( ( path_res . base_def . def_id ( ) , trait_ref . clone ( ) ) ) ;
2051
+ new_id = Some ( path_res . base_def . def_id ( ) ) ;
2057
2052
}
2058
2053
visit:: walk_trait_ref ( self , trait_ref) ;
2059
2054
}
2060
2055
let original_trait_ref = replace ( & mut self . current_trait_ref , new_val) ;
2061
- let result = f ( self ) ;
2056
+ let result = f ( self , new_id ) ;
2062
2057
self . current_trait_ref = original_trait_ref;
2063
2058
result
2064
2059
}
2065
2060
2061
+ fn with_self_rib < F > ( & mut self , self_def : Def , f : F )
2062
+ where F : FnOnce ( & mut Resolver )
2063
+ {
2064
+ let mut self_type_rib = Rib :: new ( NormalRibKind ) ;
2065
+
2066
+ // plain insert (no renaming, types are not currently hygienic....)
2067
+ let name = special_names:: type_self;
2068
+ self_type_rib. bindings . insert ( name, DlDef ( self_def) ) ;
2069
+ self . type_ribs . push ( self_type_rib) ;
2070
+ f ( self ) ;
2071
+ self . type_ribs . pop ( ) ;
2072
+ }
2073
+
2066
2074
fn resolve_implementation ( & mut self ,
2067
2075
generics : & Generics ,
2068
2076
opt_trait_reference : & Option < TraitRef > ,
2069
2077
self_type : & Ty ,
2078
+ item_id : NodeId ,
2070
2079
impl_items : & [ P < ImplItem > ] ) {
2071
2080
// If applicable, create a rib for the type parameters.
2072
2081
self . with_type_parameter_rib ( HasTypeParameters ( generics,
@@ -2077,40 +2086,42 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
2077
2086
this. visit_generics ( generics) ;
2078
2087
2079
2088
// Resolve the trait reference, if necessary.
2080
- this. with_optional_trait_ref ( opt_trait_reference. as_ref ( ) , |this| {
2089
+ this. with_optional_trait_ref ( opt_trait_reference. as_ref ( ) , |this, trait_id | {
2081
2090
// Resolve the self type.
2082
2091
this. visit_ty ( self_type) ;
2083
2092
2084
- this. with_current_self_type ( self_type, |this| {
2085
- for impl_item in impl_items {
2086
- match impl_item. node {
2087
- MethodImplItem ( ref sig, _) => {
2088
- // If this is a trait impl, ensure the method
2089
- // exists in trait
2090
- this. check_trait_item ( impl_item. ident . name ,
2091
- impl_item. span ) ;
2092
-
2093
- // We also need a new scope for the method-
2094
- // specific type parameters.
2095
- let type_parameters =
2096
- HasTypeParameters ( & sig. generics ,
2097
- FnSpace ,
2098
- MethodRibKind ) ;
2099
- this. with_type_parameter_rib ( type_parameters, |this| {
2100
- visit:: walk_impl_item ( this, impl_item) ;
2101
- } ) ;
2102
- }
2103
- TypeImplItem ( ref ty) => {
2104
- // If this is a trait impl, ensure the method
2105
- // exists in trait
2106
- this. check_trait_item ( impl_item. ident . name ,
2107
- impl_item. span ) ;
2093
+ this. with_self_rib ( DefSelfTy ( trait_id, Some ( ( item_id, self_type. id ) ) ) , |this| {
2094
+ this. with_current_self_type ( self_type, |this| {
2095
+ for impl_item in impl_items {
2096
+ match impl_item. node {
2097
+ MethodImplItem ( ref sig, _) => {
2098
+ // If this is a trait impl, ensure the method
2099
+ // exists in trait
2100
+ this. check_trait_item ( impl_item. ident . name ,
2101
+ impl_item. span ) ;
2102
+
2103
+ // We also need a new scope for the method-
2104
+ // specific type parameters.
2105
+ let type_parameters =
2106
+ HasTypeParameters ( & sig. generics ,
2107
+ FnSpace ,
2108
+ MethodRibKind ) ;
2109
+ this. with_type_parameter_rib ( type_parameters, |this| {
2110
+ visit:: walk_impl_item ( this, impl_item) ;
2111
+ } ) ;
2112
+ }
2113
+ TypeImplItem ( ref ty) => {
2114
+ // If this is a trait impl, ensure the method
2115
+ // exists in trait
2116
+ this. check_trait_item ( impl_item. ident . name ,
2117
+ impl_item. span ) ;
2108
2118
2109
- this. visit_ty ( ty) ;
2119
+ this. visit_ty ( ty) ;
2120
+ }
2121
+ ast:: MacImplItem ( _) => { }
2110
2122
}
2111
- ast:: MacImplItem ( _) => { }
2112
2123
}
2113
- }
2124
+ } ) ;
2114
2125
} ) ;
2115
2126
} ) ;
2116
2127
} ) ;
0 commit comments