@@ -15,8 +15,9 @@ use hir_def::{
15
15
use span:: Edition ;
16
16
17
17
use crate :: {
18
- InferenceResult , Interner , TargetFeatures , TyExt , TyKind , db:: HirDatabase ,
19
- utils:: is_fn_unsafe_to_call,
18
+ InferenceResult , Interner , TargetFeatures , TyExt , TyKind ,
19
+ db:: HirDatabase ,
20
+ utils:: { is_fn_unsafe_to_call, target_feature_is_safe_in_target} ,
20
21
} ;
21
22
22
23
#[ derive( Debug , Default ) ]
@@ -144,6 +145,9 @@ struct UnsafeVisitor<'db> {
144
145
def_target_features : TargetFeatures ,
145
146
// FIXME: This needs to be the edition of the span of each call.
146
147
edition : Edition ,
148
+ /// On some targets (WASM), calling safe functions with `#[target_feature]` is always safe, even when
149
+ /// the target feature is not enabled. This flag encodes that.
150
+ target_feature_is_safe : bool ,
147
151
}
148
152
149
153
impl < ' db > UnsafeVisitor < ' db > {
@@ -159,7 +163,12 @@ impl<'db> UnsafeVisitor<'db> {
159
163
DefWithBodyId :: FunctionId ( func) => TargetFeatures :: from_attrs ( & db. attrs ( func. into ( ) ) ) ,
160
164
_ => TargetFeatures :: default ( ) ,
161
165
} ;
162
- let edition = resolver. module ( ) . krate ( ) . data ( db) . edition ;
166
+ let krate = resolver. module ( ) . krate ( ) ;
167
+ let edition = krate. data ( db) . edition ;
168
+ let target_feature_is_safe = match & krate. workspace_data ( db) . target {
169
+ Ok ( target) => target_feature_is_safe_in_target ( target) ,
170
+ Err ( _) => false ,
171
+ } ;
163
172
Self {
164
173
db,
165
174
infer,
@@ -172,6 +181,7 @@ impl<'db> UnsafeVisitor<'db> {
172
181
callback : unsafe_expr_cb,
173
182
def_target_features,
174
183
edition,
184
+ target_feature_is_safe,
175
185
}
176
186
}
177
187
@@ -184,7 +194,13 @@ impl<'db> UnsafeVisitor<'db> {
184
194
}
185
195
186
196
fn check_call ( & mut self , node : ExprId , func : FunctionId ) {
187
- let unsafety = is_fn_unsafe_to_call ( self . db , func, & self . def_target_features , self . edition ) ;
197
+ let unsafety = is_fn_unsafe_to_call (
198
+ self . db ,
199
+ func,
200
+ & self . def_target_features ,
201
+ self . edition ,
202
+ self . target_feature_is_safe ,
203
+ ) ;
188
204
match unsafety {
189
205
crate :: utils:: Unsafety :: Safe => { }
190
206
crate :: utils:: Unsafety :: Unsafe => {
0 commit comments