@@ -53,7 +53,7 @@ use rustc::front::map as hir_map;
53
53
use rustc:: session:: Session ;
54
54
use rustc:: lint;
55
55
use rustc:: metadata:: csearch;
56
- use rustc:: metadata:: decoder:: { DefLike , DlDef , DlField , DlImpl } ;
56
+ use rustc:: metadata:: decoder:: { DefLike , DlDef } ;
57
57
use rustc:: middle:: def:: * ;
58
58
use rustc:: middle:: def_id:: DefId ;
59
59
use rustc:: middle:: pat_util:: pat_bindings_hygienic;
@@ -652,6 +652,21 @@ impl Rib {
652
652
}
653
653
}
654
654
655
+ /// A definition along with the index of the rib it was found on
656
+ struct LocalDef {
657
+ ribs : Option < ( Namespace , usize ) > ,
658
+ def : Def
659
+ }
660
+
661
+ impl LocalDef {
662
+ fn from_def ( def : Def ) -> Self {
663
+ LocalDef {
664
+ ribs : None ,
665
+ def : def
666
+ }
667
+ }
668
+ }
669
+
655
670
/// The link from a module up to its nearest parent node.
656
671
#[ derive( Clone , Debug ) ]
657
672
enum ParentLink {
@@ -1954,116 +1969,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
1954
1969
self . current_module = orig_module;
1955
1970
}
1956
1971
1957
- /// Wraps the given definition in the appropriate number of `DefUpvar`
1958
- /// wrappers.
1959
- fn upvarify ( & self ,
1960
- ribs : & [ Rib ] ,
1961
- def_like : DefLike ,
1962
- span : Span )
1963
- -> Option < DefLike > {
1964
- let mut def = match def_like {
1965
- DlDef ( def) => def,
1966
- _ => return Some ( def_like)
1967
- } ;
1968
- match def {
1969
- DefUpvar ( ..) => {
1970
- self . session . span_bug ( span,
1971
- & format ! ( "unexpected {:?} in bindings" , def) )
1972
- }
1973
- DefLocal ( _, node_id) => {
1974
- for rib in ribs {
1975
- match rib. kind {
1976
- NormalRibKind => {
1977
- // Nothing to do. Continue.
1978
- }
1979
- ClosureRibKind ( function_id) => {
1980
- let prev_def = def;
1981
- let node_def_id = self . ast_map . local_def_id ( node_id) ;
1982
-
1983
- let mut seen = self . freevars_seen . borrow_mut ( ) ;
1984
- let seen = seen. entry ( function_id) . or_insert_with ( || NodeMap ( ) ) ;
1985
- if let Some ( & index) = seen. get ( & node_id) {
1986
- def = DefUpvar ( node_def_id, node_id, index, function_id) ;
1987
- continue ;
1988
- }
1989
- let mut freevars = self . freevars . borrow_mut ( ) ;
1990
- let vec = freevars. entry ( function_id)
1991
- . or_insert_with ( || vec ! [ ] ) ;
1992
- let depth = vec. len ( ) ;
1993
- vec. push ( Freevar { def : prev_def, span : span } ) ;
1994
-
1995
- def = DefUpvar ( node_def_id, node_id, depth, function_id) ;
1996
- seen. insert ( node_id, depth) ;
1997
- }
1998
- ItemRibKind | MethodRibKind => {
1999
- // This was an attempt to access an upvar inside a
2000
- // named function item. This is not allowed, so we
2001
- // report an error.
2002
- resolve_error (
2003
- self ,
2004
- span,
2005
- ResolutionError :: CannotCaptureDynamicEnvironmentInFnItem
2006
- ) ;
2007
- return None ;
2008
- }
2009
- ConstantItemRibKind => {
2010
- // Still doesn't deal with upvars
2011
- resolve_error (
2012
- self ,
2013
- span,
2014
- ResolutionError :: AttemptToUseNonConstantValueInConstant
2015
- ) ;
2016
- return None ;
2017
- }
2018
- }
2019
- }
2020
- }
2021
- DefTyParam ( ..) | DefSelfTy ( ..) => {
2022
- for rib in ribs {
2023
- match rib. kind {
2024
- NormalRibKind | MethodRibKind | ClosureRibKind ( ..) => {
2025
- // Nothing to do. Continue.
2026
- }
2027
- ItemRibKind => {
2028
- // This was an attempt to use a type parameter outside
2029
- // its scope.
2030
-
2031
- resolve_error ( self ,
2032
- span,
2033
- ResolutionError :: TypeParametersFromOuterFunction ) ;
2034
- return None ;
2035
- }
2036
- ConstantItemRibKind => {
2037
- // see #9186
2038
- resolve_error ( self , span, ResolutionError :: OuterTypeParameterContext ) ;
2039
- return None ;
2040
- }
2041
- }
2042
- }
2043
- }
2044
- _ => { }
2045
- }
2046
- Some ( DlDef ( def) )
2047
- }
2048
-
2049
- /// Searches the current set of local scopes and
2050
- /// applies translations for closures.
2051
- fn search_ribs ( & self ,
2052
- ribs : & [ Rib ] ,
2053
- name : Name ,
2054
- span : Span )
2055
- -> Option < DefLike > {
2056
- // FIXME #4950: Try caching?
2057
-
2058
- for ( i, rib) in ribs. iter ( ) . enumerate ( ) . rev ( ) {
2059
- if let Some ( def_like) = rib. bindings . get ( & name) . cloned ( ) {
2060
- return self . upvarify ( & ribs[ i + 1 ..] , def_like, span) ;
2061
- }
2062
- }
2063
-
2064
- None
2065
- }
2066
-
2067
1972
/// Searches the current set of local scopes for labels.
2068
1973
/// Stops after meeting a closure.
2069
1974
fn search_label ( & self , name : Name ) -> Option < DefLike > {
@@ -3123,19 +3028,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3123
3028
}
3124
3029
3125
3030
// Try to find a path to an item in a module.
3126
- let unqualified_def =
3127
- self . resolve_identifier ( segments. last ( ) . unwrap ( ) . identifier ,
3128
- namespace,
3129
- check_ribs,
3130
- span) ;
3031
+ let unqualified_def = self . resolve_identifier (
3032
+ segments. last ( ) . unwrap ( ) . identifier ,
3033
+ namespace, check_ribs) ;
3131
3034
3132
3035
if segments. len ( ) <= 1 {
3133
- return unqualified_def. map ( mk_res) ;
3036
+ return unqualified_def
3037
+ . and_then ( |def| self . adjust_local_def ( def, span) )
3038
+ . map ( |def| {
3039
+ PathResolution :: new ( def, LastMod ( AllPublic ) , path_depth)
3040
+ } ) ;
3134
3041
}
3135
3042
3136
3043
let def = self . resolve_module_relative_path ( span, segments, namespace) ;
3137
3044
match ( def, unqualified_def) {
3138
- ( Some ( ( ref d, _) ) , Some ( ( ref ud, _ ) ) ) if * d == * ud => {
3045
+ ( Some ( ( ref d, _) ) , Some ( ref ud) ) if * d == ud . def => {
3139
3046
self . session
3140
3047
. add_lint ( lint:: builtin:: UNUSED_QUALIFICATIONS ,
3141
3048
id, span,
@@ -3147,31 +3054,119 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3147
3054
def. map ( mk_res)
3148
3055
}
3149
3056
3150
- // Resolve a single identifier.
3057
+ // Resolve a single identifier
3151
3058
fn resolve_identifier ( & mut self ,
3152
3059
identifier : Ident ,
3153
3060
namespace : Namespace ,
3154
- check_ribs : bool ,
3155
- span : Span )
3156
- -> Option < ( Def , LastPrivate ) > {
3061
+ check_ribs : bool )
3062
+ -> Option < LocalDef > {
3157
3063
// First, check to see whether the name is a primitive type.
3158
3064
if namespace == TypeNS {
3159
3065
if let Some ( & prim_ty) = self . primitive_type_table
3160
3066
. primitive_types
3161
3067
. get ( & identifier. name ) {
3162
- return Some ( ( DefPrimTy ( prim_ty) , LastMod ( AllPublic ) ) ) ;
3068
+ return Some ( LocalDef :: from_def ( DefPrimTy ( prim_ty) ) ) ;
3163
3069
}
3164
3070
}
3165
3071
3166
3072
if check_ribs {
3167
3073
if let Some ( def) = self . resolve_identifier_in_local_ribs ( identifier,
3168
- namespace,
3169
- span) {
3170
- return Some ( ( def, LastMod ( AllPublic ) ) ) ;
3074
+ namespace) {
3075
+ return Some ( def) ;
3171
3076
}
3172
3077
}
3173
3078
3174
3079
self . resolve_item_by_name_in_lexical_scope ( identifier. name , namespace)
3080
+ . map ( LocalDef :: from_def)
3081
+ }
3082
+
3083
+ // Resolve a local definition, potentially adjusting for closures.
3084
+ fn adjust_local_def ( & self , local_def : LocalDef , span : Span ) -> Option < Def > {
3085
+ let ribs = match local_def. ribs {
3086
+ Some ( ( TypeNS , i) ) => & self . type_ribs [ i+1 ..] ,
3087
+ Some ( ( ValueNS , i) ) => & self . value_ribs [ i+1 ..] ,
3088
+ _ => & [ ] as & [ _ ]
3089
+ } ;
3090
+ let mut def = local_def. def ;
3091
+ match def {
3092
+ DefUpvar ( ..) => {
3093
+ self . session . span_bug ( span,
3094
+ & format ! ( "unexpected {:?} in bindings" , def) )
3095
+ }
3096
+ DefLocal ( _, node_id) => {
3097
+ for rib in ribs {
3098
+ match rib. kind {
3099
+ NormalRibKind => {
3100
+ // Nothing to do. Continue.
3101
+ }
3102
+ ClosureRibKind ( function_id) => {
3103
+ let prev_def = def;
3104
+ let node_def_id = self . ast_map . local_def_id ( node_id) ;
3105
+
3106
+ let mut seen = self . freevars_seen . borrow_mut ( ) ;
3107
+ let seen = seen. entry ( function_id) . or_insert_with ( || NodeMap ( ) ) ;
3108
+ if let Some ( & index) = seen. get ( & node_id) {
3109
+ def = DefUpvar ( node_def_id, node_id, index, function_id) ;
3110
+ continue ;
3111
+ }
3112
+ let mut freevars = self . freevars . borrow_mut ( ) ;
3113
+ let vec = freevars. entry ( function_id)
3114
+ . or_insert_with ( || vec ! [ ] ) ;
3115
+ let depth = vec. len ( ) ;
3116
+ vec. push ( Freevar { def : prev_def, span : span } ) ;
3117
+
3118
+ def = DefUpvar ( node_def_id, node_id, depth, function_id) ;
3119
+ seen. insert ( node_id, depth) ;
3120
+ }
3121
+ ItemRibKind | MethodRibKind => {
3122
+ // This was an attempt to access an upvar inside a
3123
+ // named function item. This is not allowed, so we
3124
+ // report an error.
3125
+ resolve_error (
3126
+ self ,
3127
+ span,
3128
+ ResolutionError :: CannotCaptureDynamicEnvironmentInFnItem
3129
+ ) ;
3130
+ return None ;
3131
+ }
3132
+ ConstantItemRibKind => {
3133
+ // Still doesn't deal with upvars
3134
+ resolve_error (
3135
+ self ,
3136
+ span,
3137
+ ResolutionError :: AttemptToUseNonConstantValueInConstant
3138
+ ) ;
3139
+ return None ;
3140
+ }
3141
+ }
3142
+ }
3143
+ }
3144
+ DefTyParam ( ..) | DefSelfTy ( ..) => {
3145
+ for rib in ribs {
3146
+ match rib. kind {
3147
+ NormalRibKind | MethodRibKind | ClosureRibKind ( ..) => {
3148
+ // Nothing to do. Continue.
3149
+ }
3150
+ ItemRibKind => {
3151
+ // This was an attempt to use a type parameter outside
3152
+ // its scope.
3153
+
3154
+ resolve_error ( self ,
3155
+ span,
3156
+ ResolutionError :: TypeParametersFromOuterFunction ) ;
3157
+ return None ;
3158
+ }
3159
+ ConstantItemRibKind => {
3160
+ // see #9186
3161
+ resolve_error ( self , span, ResolutionError :: OuterTypeParameterContext ) ;
3162
+ return None ;
3163
+ }
3164
+ }
3165
+ }
3166
+ }
3167
+ _ => { }
3168
+ }
3169
+ return Some ( def) ;
3175
3170
}
3176
3171
3177
3172
// FIXME #4952: Merge me with resolve_name_in_module?
@@ -3364,38 +3359,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3364
3359
3365
3360
fn resolve_identifier_in_local_ribs ( & mut self ,
3366
3361
ident : Ident ,
3367
- namespace : Namespace ,
3368
- span : Span )
3369
- -> Option < Def > {
3362
+ namespace : Namespace )
3363
+ -> Option < LocalDef > {
3370
3364
// Check the local set of ribs.
3371
- let search_result = match namespace {
3372
- ValueNS => {
3373
- let renamed = mtwt:: resolve ( ident) ;
3374
- self . search_ribs ( & self . value_ribs , renamed, span)
3375
- }
3376
- TypeNS => {
3377
- let name = ident. name ;
3378
- self . search_ribs ( & self . type_ribs , name, span)
3379
- }
3365
+ let ( name, ribs) = match namespace {
3366
+ ValueNS => ( mtwt:: resolve ( ident) , & self . value_ribs ) ,
3367
+ TypeNS => ( ident. name , & self . type_ribs )
3380
3368
} ;
3381
3369
3382
- match search_result {
3383
- Some ( DlDef ( def) ) => {
3384
- debug ! ( "(resolving path in local ribs) resolved `{}` to local: {:?}" ,
3385
- ident,
3386
- def) ;
3387
- Some ( def)
3388
- }
3389
- Some ( DlField ) | Some ( DlImpl ( _) ) | None => {
3390
- None
3370
+ for ( i, rib) in ribs. iter ( ) . enumerate ( ) . rev ( ) {
3371
+ if let Some ( def_like) = rib. bindings . get ( & name) . cloned ( ) {
3372
+ match def_like {
3373
+ DlDef ( def) => {
3374
+ debug ! ( "(resolving path in local ribs) resolved `{}` to {:?} at {}" ,
3375
+ name, def, i) ;
3376
+ return Some ( LocalDef {
3377
+ ribs : Some ( ( namespace, i) ) ,
3378
+ def : def
3379
+ } ) ;
3380
+ }
3381
+ def_like => {
3382
+ debug ! ( "(resolving path in local ribs) resolved `{}` to pseudo-def {:?}" ,
3383
+ name, def_like) ;
3384
+ return None ;
3385
+ }
3386
+ }
3391
3387
}
3392
3388
}
3389
+
3390
+ None
3393
3391
}
3394
3392
3395
3393
fn resolve_item_by_name_in_lexical_scope ( & mut self ,
3396
3394
name : Name ,
3397
3395
namespace : Namespace )
3398
- -> Option < ( Def , LastPrivate ) > {
3396
+ -> Option < Def > {
3399
3397
// Check the items.
3400
3398
let module = self . current_module . clone ( ) ;
3401
3399
match self . resolve_item_in_lexical_scope ( module,
@@ -3409,7 +3407,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3409
3407
debug ! ( "(resolving item path by identifier in lexical \
3410
3408
scope) failed to resolve {} after success...",
3411
3409
name) ;
3412
- return None ;
3410
+ None
3413
3411
}
3414
3412
Some ( def) => {
3415
3413
debug ! ( "(resolving item path in lexical scope) \
@@ -3418,7 +3416,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3418
3416
// This lookup is "all public" because it only searched
3419
3417
// for one identifier in the current module (couldn't
3420
3418
// have passed through reexports or anything like that.
3421
- return Some ( ( def, LastMod ( AllPublic ) ) ) ;
3419
+ Some ( def)
3422
3420
}
3423
3421
}
3424
3422
}
@@ -3433,7 +3431,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
3433
3431
resolve_error ( self , span, ResolutionError :: FailedToResolve ( & * msg) )
3434
3432
}
3435
3433
3436
- return None ;
3434
+ None
3437
3435
}
3438
3436
}
3439
3437
}
0 commit comments