@@ -53,7 +53,7 @@ use rustc::front::map as hir_map;
5353use rustc:: session:: Session ;
5454use rustc:: lint;
5555use rustc:: metadata:: csearch;
56- use rustc:: metadata:: decoder:: { DefLike , DlDef , DlField , DlImpl } ;
56+ use rustc:: metadata:: decoder:: { DefLike , DlDef } ;
5757use rustc:: middle:: def:: * ;
5858use rustc:: middle:: def_id:: DefId ;
5959use rustc:: middle:: pat_util:: pat_bindings_hygienic;
@@ -652,6 +652,21 @@ impl Rib {
652652 }
653653}
654654
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+
655670/// The link from a module up to its nearest parent node.
656671#[ derive( Clone , Debug ) ]
657672enum ParentLink {
@@ -1954,116 +1969,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
19541969 self . current_module = orig_module;
19551970 }
19561971
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-
20671972 /// Searches the current set of local scopes for labels.
20681973 /// Stops after meeting a closure.
20691974 fn search_label ( & self , name : Name ) -> Option < DefLike > {
@@ -3123,19 +3028,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
31233028 }
31243029
31253030 // 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) ;
31313034
31323035 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+ } ) ;
31343041 }
31353042
31363043 let def = self . resolve_module_relative_path ( span, segments, namespace) ;
31373044 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 => {
31393046 self . session
31403047 . add_lint ( lint:: builtin:: UNUSED_QUALIFICATIONS ,
31413048 id, span,
@@ -3147,31 +3054,119 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
31473054 def. map ( mk_res)
31483055 }
31493056
3150- // Resolve a single identifier.
3057+ // Resolve a single identifier
31513058 fn resolve_identifier ( & mut self ,
31523059 identifier : Ident ,
31533060 namespace : Namespace ,
3154- check_ribs : bool ,
3155- span : Span )
3156- -> Option < ( Def , LastPrivate ) > {
3061+ check_ribs : bool )
3062+ -> Option < LocalDef > {
31573063 // First, check to see whether the name is a primitive type.
31583064 if namespace == TypeNS {
31593065 if let Some ( & prim_ty) = self . primitive_type_table
31603066 . primitive_types
31613067 . get ( & identifier. name ) {
3162- return Some ( ( DefPrimTy ( prim_ty) , LastMod ( AllPublic ) ) ) ;
3068+ return Some ( LocalDef :: from_def ( DefPrimTy ( prim_ty) ) ) ;
31633069 }
31643070 }
31653071
31663072 if check_ribs {
31673073 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) ;
31713076 }
31723077 }
31733078
31743079 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) ;
31753170 }
31763171
31773172 // FIXME #4952: Merge me with resolve_name_in_module?
@@ -3364,38 +3359,41 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
33643359
33653360 fn resolve_identifier_in_local_ribs ( & mut self ,
33663361 ident : Ident ,
3367- namespace : Namespace ,
3368- span : Span )
3369- -> Option < Def > {
3362+ namespace : Namespace )
3363+ -> Option < LocalDef > {
33703364 // 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 )
33803368 } ;
33813369
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+ }
33913387 }
33923388 }
3389+
3390+ None
33933391 }
33943392
33953393 fn resolve_item_by_name_in_lexical_scope ( & mut self ,
33963394 name : Name ,
33973395 namespace : Namespace )
3398- -> Option < ( Def , LastPrivate ) > {
3396+ -> Option < Def > {
33993397 // Check the items.
34003398 let module = self . current_module . clone ( ) ;
34013399 match self . resolve_item_in_lexical_scope ( module,
@@ -3409,7 +3407,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
34093407 debug ! ( "(resolving item path by identifier in lexical \
34103408 scope) failed to resolve {} after success...",
34113409 name) ;
3412- return None ;
3410+ None
34133411 }
34143412 Some ( def) => {
34153413 debug ! ( "(resolving item path in lexical scope) \
@@ -3418,7 +3416,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
34183416 // This lookup is "all public" because it only searched
34193417 // for one identifier in the current module (couldn't
34203418 // have passed through reexports or anything like that.
3421- return Some ( ( def, LastMod ( AllPublic ) ) ) ;
3419+ Some ( def)
34223420 }
34233421 }
34243422 }
@@ -3433,7 +3431,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
34333431 resolve_error ( self , span, ResolutionError :: FailedToResolve ( & * msg) )
34343432 }
34353433
3436- return None ;
3434+ None
34373435 }
34383436 }
34393437 }
0 commit comments