@@ -2,12 +2,12 @@ pub mod convert;
2
2
3
3
use std:: cmp;
4
4
use std:: iter;
5
- use std:: mem;
6
5
use std:: num:: NonZeroUsize ;
7
6
use std:: time:: Duration ;
8
7
9
8
use log:: trace;
10
9
10
+ use rustc_hir:: def:: { DefKind , Namespace } ;
11
11
use rustc_hir:: def_id:: { DefId , CRATE_DEF_INDEX } ;
12
12
use rustc_middle:: mir;
13
13
use rustc_middle:: ty:: {
@@ -74,48 +74,51 @@ const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
74
74
} ;
75
75
76
76
/// Gets an instance for a path.
77
- fn try_resolve_did < ' tcx > ( tcx : TyCtxt < ' tcx > , path : & [ & str ] ) -> Option < DefId > {
77
+ fn try_resolve_did < ' tcx > ( tcx : TyCtxt < ' tcx > , path : & [ & str ] , namespace : Namespace ) -> Option < DefId > {
78
78
tcx. crates ( ( ) ) . iter ( ) . find ( |& & krate| tcx. crate_name ( krate) . as_str ( ) == path[ 0 ] ) . and_then (
79
79
|krate| {
80
80
let krate = DefId { krate : * krate, index : CRATE_DEF_INDEX } ;
81
81
let mut items = tcx. module_children ( krate) ;
82
- let mut path_it = path. iter ( ) . skip ( 1 ) . peekable ( ) ;
83
82
84
- while let Some ( segment) = path_it. next ( ) {
85
- for item in mem:: take ( & mut items) . iter ( ) {
86
- if item. ident . name . as_str ( ) == * segment {
87
- if path_it. peek ( ) . is_none ( ) {
88
- return Some ( item. res . def_id ( ) ) ;
89
- }
83
+ for & segment in & path[ 1 ..path. len ( ) - 1 ] {
84
+ let next_mod = items. iter ( ) . find ( |item| {
85
+ item. ident . name . as_str ( ) == segment
86
+ && tcx. def_kind ( item. res . def_id ( ) ) == DefKind :: Mod
87
+ } ) ?;
90
88
91
- items = tcx. module_children ( item. res . def_id ( ) ) ;
92
- break ;
93
- }
94
- }
89
+ items = tcx. module_children ( next_mod. res . def_id ( ) ) ;
95
90
}
96
- None
91
+
92
+ let item_name = * path. last ( ) . unwrap ( ) ;
93
+
94
+ let item = items. iter ( ) . find ( |item| {
95
+ item. ident . name . as_str ( ) == item_name
96
+ && tcx. def_kind ( item. res . def_id ( ) ) . ns ( ) == Some ( namespace)
97
+ } ) ?;
98
+
99
+ Some ( item. res . def_id ( ) )
97
100
} ,
98
101
)
99
102
}
100
103
101
104
pub trait EvalContextExt < ' mir , ' tcx : ' mir > : crate :: MiriInterpCxExt < ' mir , ' tcx > {
102
105
/// Gets an instance for a path; fails gracefully if the path does not exist.
103
- fn try_resolve_path ( & self , path : & [ & str ] ) -> Option < ty:: Instance < ' tcx > > {
104
- let did = try_resolve_did ( self . eval_context_ref ( ) . tcx . tcx , path) ?;
106
+ fn try_resolve_path ( & self , path : & [ & str ] , namespace : Namespace ) -> Option < ty:: Instance < ' tcx > > {
107
+ let did = try_resolve_did ( self . eval_context_ref ( ) . tcx . tcx , path, namespace ) ?;
105
108
Some ( ty:: Instance :: mono ( self . eval_context_ref ( ) . tcx . tcx , did) )
106
109
}
107
110
108
111
/// Gets an instance for a path.
109
- fn resolve_path ( & self , path : & [ & str ] ) -> ty:: Instance < ' tcx > {
110
- self . try_resolve_path ( path)
112
+ fn resolve_path ( & self , path : & [ & str ] , namespace : Namespace ) -> ty:: Instance < ' tcx > {
113
+ self . try_resolve_path ( path, namespace )
111
114
. unwrap_or_else ( || panic ! ( "failed to find required Rust item: {path:?}" ) )
112
115
}
113
116
114
117
/// Evaluates the scalar at the specified path. Returns Some(val)
115
118
/// if the path could be resolved, and None otherwise
116
119
fn eval_path_scalar ( & self , path : & [ & str ] ) -> InterpResult < ' tcx , Scalar < Provenance > > {
117
120
let this = self . eval_context_ref ( ) ;
118
- let instance = this. resolve_path ( path) ;
121
+ let instance = this. resolve_path ( path, Namespace :: ValueNS ) ;
119
122
let cid = GlobalId { instance, promoted : None } ;
120
123
// We don't give a span -- this isn't actually used directly by the program anyway.
121
124
let const_val = this. eval_global ( cid, None ) ?;
@@ -147,15 +150,17 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
147
150
/// Helper function to get the `TyAndLayout` of a `libc` type
148
151
fn libc_ty_layout ( & self , name : & str ) -> InterpResult < ' tcx , TyAndLayout < ' tcx > > {
149
152
let this = self . eval_context_ref ( ) ;
150
- let ty = this. resolve_path ( & [ "libc" , name] ) . ty ( * this. tcx , ty:: ParamEnv :: reveal_all ( ) ) ;
153
+ let ty = this
154
+ . resolve_path ( & [ "libc" , name] , Namespace :: TypeNS )
155
+ . ty ( * this. tcx , ty:: ParamEnv :: reveal_all ( ) ) ;
151
156
this. layout_of ( ty)
152
157
}
153
158
154
159
/// Helper function to get the `TyAndLayout` of a `windows` type
155
160
fn windows_ty_layout ( & self , name : & str ) -> InterpResult < ' tcx , TyAndLayout < ' tcx > > {
156
161
let this = self . eval_context_ref ( ) ;
157
162
let ty = this
158
- . resolve_path ( & [ "std" , "sys" , "windows" , "c" , name] )
163
+ . resolve_path ( & [ "std" , "sys" , "windows" , "c" , name] , Namespace :: TypeNS )
159
164
. ty ( * this. tcx , ty:: ParamEnv :: reveal_all ( ) ) ;
160
165
this. layout_of ( ty)
161
166
}
0 commit comments