Skip to content

Commit e88c49c

Browse files
committed
acquire more accurate HirId for ABI check lints
1 parent 61e24e6 commit e88c49c

File tree

1 file changed

+37
-19
lines changed

1 file changed

+37
-19
lines changed

compiler/rustc_monomorphize/src/mono_checks/abi_check.rs

+37-19
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! This module ensures that if a function's ABI requires a particular target feature,
22
//! that target feature is enabled both on the callee and all callers.
33
use rustc_abi::{BackendRepr, RegKind};
4-
use rustc_hir::CRATE_HIR_ID;
5-
use rustc_middle::mir::{self, traversal};
4+
use rustc_hir::{CRATE_HIR_ID, HirId};
5+
use rustc_middle::mir::{self, Location, traversal};
66
use rustc_middle::ty::layout::LayoutCx;
77
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypingEnv};
88
use rustc_session::lint::builtin::{ABI_UNSUPPORTED_VECTOR_TYPES, WASM_C_ABI};
@@ -33,7 +33,7 @@ fn do_check_simd_vector_abi<'tcx>(
3333
abi: &FnAbi<'tcx, Ty<'tcx>>,
3434
def_id: DefId,
3535
is_call: bool,
36-
span: impl Fn() -> Span,
36+
loc: impl Fn() -> (Span, HirId),
3737
) {
3838
// We check this on all functions, including those using the "Rust" ABI.
3939
// For the "Rust" ABI it would be a bug if the lint ever triggered, but better safe than sorry.
@@ -50,10 +50,10 @@ fn do_check_simd_vector_abi<'tcx>(
5050
let feature = match feature_def.iter().find(|(bits, _)| size.bits() <= *bits) {
5151
Some((_, feature)) => feature,
5252
None => {
53-
let span = span();
53+
let (span, hir_id) = loc();
5454
tcx.emit_node_span_lint(
5555
ABI_UNSUPPORTED_VECTOR_TYPES,
56-
CRATE_HIR_ID,
56+
hir_id,
5757
span,
5858
errors::AbiErrorUnsupportedVectorType {
5959
span,
@@ -66,10 +66,10 @@ fn do_check_simd_vector_abi<'tcx>(
6666
};
6767
if !have_feature(Symbol::intern(feature)) {
6868
// Emit error.
69-
let span = span();
69+
let (span, hir_id) = loc();
7070
tcx.emit_node_span_lint(
7171
ABI_UNSUPPORTED_VECTOR_TYPES,
72-
CRATE_HIR_ID,
72+
hir_id,
7373
span,
7474
errors::AbiErrorDisabledVectorType {
7575
span,
@@ -83,8 +83,9 @@ fn do_check_simd_vector_abi<'tcx>(
8383
}
8484
// The `vectorcall` ABI is special in that it requires SSE2 no matter which types are being passed.
8585
if abi.conv == Conv::X86VectorCall && !have_feature(sym::sse2) {
86+
let (span, _hir_id) = loc();
8687
tcx.dcx().emit_err(errors::AbiRequiredTargetFeature {
87-
span: span(),
88+
span,
8889
required_feature: "sse2",
8990
abi: "vectorcall",
9091
is_call,
@@ -119,7 +120,7 @@ fn do_check_wasm_abi<'tcx>(
119120
tcx: TyCtxt<'tcx>,
120121
abi: &FnAbi<'tcx, Ty<'tcx>>,
121122
is_call: bool,
122-
span: impl Fn() -> Span,
123+
loc: impl Fn() -> (Span, HirId),
123124
) {
124125
// Only proceed for `extern "C" fn` on wasm32-unknown-unknown (same check as what `adjust_for_foreign_abi` uses to call `compute_wasm_abi_info`),
125126
// and only proceed if `wasm_c_abi_opt` indicates we should emit the lint.
@@ -135,10 +136,10 @@ fn do_check_wasm_abi<'tcx>(
135136
if wasm_abi_safe(tcx, arg_abi) {
136137
continue;
137138
}
138-
let span = span();
139+
let (span, hir_id) = loc();
139140
tcx.emit_node_span_lint(
140141
WASM_C_ABI,
141-
CRATE_HIR_ID,
142+
hir_id,
142143
span,
143144
errors::WasmCAbiTransition { ty: arg_abi.layout.ty, is_call },
144145
);
@@ -157,19 +158,24 @@ fn check_instance_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>) {
157158
// function.
158159
return;
159160
};
160-
do_check_simd_vector_abi(tcx, abi, instance.def_id(), /*is_call*/ false, || {
161-
tcx.def_span(instance.def_id())
162-
});
163-
do_check_wasm_abi(tcx, abi, /*is_call*/ false, || tcx.def_span(instance.def_id()));
161+
let loc = || {
162+
let def_id = instance.def_id();
163+
(
164+
tcx.def_span(def_id),
165+
def_id.as_local().map(|did| tcx.local_def_id_to_hir_id(did)).unwrap_or(CRATE_HIR_ID),
166+
)
167+
};
168+
do_check_simd_vector_abi(tcx, abi, instance.def_id(), /*is_call*/ false, loc);
169+
do_check_wasm_abi(tcx, abi, /*is_call*/ false, loc);
164170
}
165171

166172
/// Checks that a call expression does not try to pass a vector-passed argument which requires a
167173
/// target feature that the caller does not have, as doing so causes UB because of ABI mismatch.
168174
fn check_call_site_abi<'tcx>(
169175
tcx: TyCtxt<'tcx>,
170176
callee: Ty<'tcx>,
171-
span: Span,
172177
caller: InstanceKind<'tcx>,
178+
loc: impl Fn() -> (Span, HirId) + Copy,
173179
) {
174180
if callee.fn_sig(tcx).abi().is_rustic_abi() {
175181
// we directly handle the soundness of Rust ABIs
@@ -197,8 +203,8 @@ fn check_call_site_abi<'tcx>(
197203
// ABI failed to compute; this will not get through codegen.
198204
return;
199205
};
200-
do_check_simd_vector_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, || span);
201-
do_check_wasm_abi(tcx, callee_abi, /*is_call*/ true, || span);
206+
do_check_simd_vector_abi(tcx, callee_abi, caller.def_id(), /*is_call*/ true, loc);
207+
do_check_wasm_abi(tcx, callee_abi, /*is_call*/ true, loc);
202208
}
203209

204210
fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &mir::Body<'tcx>) {
@@ -214,7 +220,19 @@ fn check_callees_abi<'tcx>(tcx: TyCtxt<'tcx>, instance: Instance<'tcx>, body: &m
214220
ty::TypingEnv::fully_monomorphized(),
215221
ty::EarlyBinder::bind(callee_ty),
216222
);
217-
check_call_site_abi(tcx, callee_ty, *fn_span, body.source.instance);
223+
check_call_site_abi(tcx, callee_ty, body.source.instance, || {
224+
let loc = Location {
225+
block: bb,
226+
statement_index: body.basic_blocks[bb].statements.len(),
227+
};
228+
(
229+
*fn_span,
230+
body.source_info(loc)
231+
.scope
232+
.lint_root(&body.source_scopes)
233+
.unwrap_or(CRATE_HIR_ID),
234+
)
235+
});
218236
}
219237
_ => {}
220238
}

0 commit comments

Comments
 (0)