Skip to content

Commit 944734d

Browse files
committed
Don't look at static items' HIR for wfcheck
1 parent 3e25828 commit 944734d

File tree

4 files changed

+40
-48
lines changed

4 files changed

+40
-48
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4828,6 +4828,10 @@ impl<'hir> Node<'hir> {
48284828
ImplItemKind::Type(ty) => Some(ty),
48294829
_ => None,
48304830
},
4831+
Node::ForeignItem(it) => match it.kind {
4832+
ForeignItemKind::Static(ty, ..) => Some(ty),
4833+
_ => None,
4834+
},
48314835
_ => None,
48324836
}
48334837
}

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -701,11 +701,12 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
701701
}
702702
}
703703

704-
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
704+
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
705705
match tcx.def_kind(def_id) {
706706
DefKind::Static { .. } => {
707707
check_static_inhabited(tcx, def_id);
708708
check_static_linkage(tcx, def_id);
709+
wfcheck::check_static_item(tcx, def_id)?;
709710
}
710711
DefKind::Const => {}
711712
DefKind::Enum => {
@@ -723,13 +724,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
723724
}
724725
DefKind::Impl { of_trait } => {
725726
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
726-
if tcx
727-
.ensure_ok()
728-
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
729-
.is_ok()
730-
{
731-
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
732-
}
727+
tcx.ensure_ok()
728+
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)?;
729+
730+
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
733731
}
734732
}
735733
DefKind::Trait => {
@@ -775,11 +773,8 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
775773
check_type_alias_type_params_are_used(tcx, def_id);
776774
}
777775
DefKind::ForeignMod => {
778-
let it = tcx.hir_expect_item(def_id);
779-
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
780-
return;
781-
};
782-
check_abi(tcx, it.span, abi);
776+
let (abi, items) = tcx.hir_expect_item(def_id).expect_foreign_mod();
777+
check_abi(tcx, tcx.def_span(def_id), abi);
783778

784779
for item in items {
785780
let def_id = item.id.owner_id.def_id;
@@ -825,6 +820,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
825820
}
826821
_ => {}
827822
}
823+
Ok(())
828824
}
829825

830826
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) {

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 19 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,17 @@ where
186186
}
187187

188188
fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
189-
crate::check::check::check_item_type(tcx, def_id);
189+
let mut res = crate::check::check::check_item_type(tcx, def_id);
190190
let node = tcx.hir_node_by_def_id(def_id);
191-
let mut res = match node {
191+
res = res.and(match node {
192192
hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
193193
hir::Node::Item(item) => check_item(tcx, item),
194194
hir::Node::TraitItem(item) => check_trait_item(tcx, item),
195195
hir::Node::ImplItem(item) => check_impl_item(tcx, item),
196196
hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
197197
hir::Node::OpaqueTy(_) => Ok(()),
198198
_ => unreachable!("{node:?}"),
199-
};
199+
});
200200

201201
for param in &tcx.generics_of(def_id).own_params {
202202
res = res.and(check_param_wf(tcx, param));
@@ -292,9 +292,6 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) -> Result<()
292292
res
293293
}
294294
hir::ItemKind::Fn { ident, sig, .. } => check_item_fn(tcx, def_id, ident, sig.decl),
295-
hir::ItemKind::Static(_, _, ty, _) => {
296-
check_static_item(tcx, def_id, ty.span, UnsizedHandling::Forbid)
297-
}
298295
hir::ItemKind::Const(_, _, ty, _) => check_const_item(tcx, def_id, ty.span, item.span),
299296
hir::ItemKind::Struct(_, generics, _) => {
300297
let res = check_type_defn(tcx, item, false);
@@ -350,10 +347,7 @@ fn check_foreign_item<'tcx>(
350347

351348
match item.kind {
352349
hir::ForeignItemKind::Fn(sig, ..) => check_item_fn(tcx, def_id, item.ident, sig.decl),
353-
hir::ForeignItemKind::Static(ty, ..) => {
354-
check_static_item(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
355-
}
356-
hir::ForeignItemKind::Type => Ok(()),
350+
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => Ok(()),
357351
}
358352
}
359353

@@ -1315,61 +1309,52 @@ fn check_item_fn(
13151309
})
13161310
}
13171311

1318-
enum UnsizedHandling {
1319-
Forbid,
1320-
AllowIfForeignTail,
1321-
}
1322-
1323-
#[instrument(level = "debug", skip(tcx, ty_span, unsized_handling))]
1324-
fn check_static_item(
1312+
#[instrument(level = "debug", skip(tcx))]
1313+
pub(super) fn check_static_item(
13251314
tcx: TyCtxt<'_>,
13261315
item_id: LocalDefId,
1327-
ty_span: Span,
1328-
unsized_handling: UnsizedHandling,
13291316
) -> Result<(), ErrorGuaranteed> {
13301317
enter_wf_checking_ctxt(tcx, item_id, |wfcx| {
13311318
let ty = tcx.type_of(item_id).instantiate_identity();
1332-
let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
1333-
1334-
let forbid_unsized = match unsized_handling {
1335-
UnsizedHandling::Forbid => true,
1336-
UnsizedHandling::AllowIfForeignTail => {
1337-
let tail =
1338-
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
1339-
!matches!(tail.kind(), ty::Foreign(_))
1340-
}
1319+
let item_ty = wfcx.deeply_normalize(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), ty);
1320+
1321+
let is_foreign_item = tcx.is_foreign_item(item_id);
1322+
1323+
let forbid_unsized = !is_foreign_item || {
1324+
let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
1325+
!matches!(tail.kind(), ty::Foreign(_))
13411326
};
13421327

1343-
wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
1328+
wfcx.register_wf_obligation(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
13441329
if forbid_unsized {
13451330
wfcx.register_bound(
13461331
traits::ObligationCause::new(
1347-
ty_span,
1332+
DUMMY_SP,
13481333
wfcx.body_def_id,
13491334
ObligationCauseCode::SizedConstOrStatic,
13501335
),
13511336
wfcx.param_env,
13521337
item_ty,
1353-
tcx.require_lang_item(LangItem::Sized, Some(ty_span)),
1338+
tcx.require_lang_item(LangItem::Sized, Some(tcx.def_span(item_id))),
13541339
);
13551340
}
13561341

13571342
// Ensure that the end result is `Sync` in a non-thread local `static`.
13581343
let should_check_for_sync = tcx.static_mutability(item_id.to_def_id())
13591344
== Some(hir::Mutability::Not)
1360-
&& !tcx.is_foreign_item(item_id.to_def_id())
1345+
&& !is_foreign_item
13611346
&& !tcx.is_thread_local_static(item_id.to_def_id());
13621347

13631348
if should_check_for_sync {
13641349
wfcx.register_bound(
13651350
traits::ObligationCause::new(
1366-
ty_span,
1351+
DUMMY_SP,
13671352
wfcx.body_def_id,
13681353
ObligationCauseCode::SharedStatic,
13691354
),
13701355
wfcx.param_env,
13711356
item_ty,
1372-
tcx.require_lang_item(LangItem::Sync, Some(ty_span)),
1357+
tcx.require_lang_item(LangItem::Sync, Some(tcx.def_span(item_id))),
13731358
);
13741359
}
13751360
Ok(())

compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use rustc_middle::ty::{
3131
};
3232
use rustc_middle::{bug, span_bug};
3333
use rustc_span::{BytePos, DUMMY_SP, STDLIB_STABLE_CRATES, Span, Symbol, sym};
34-
use tracing::{debug, instrument};
34+
use tracing::{debug, instrument, trace};
3535

3636
use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote};
3737
use super::suggestions::get_explanation_based_on_obligation;
@@ -67,6 +67,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
6767

6868
let mut err = match *error {
6969
SelectionError::Unimplemented => {
70+
trace!(?root_obligation.cause);
7071
// If this obligation was generated as a result of well-formedness checking, see if we
7172
// can get a better error message by performing HIR-based well-formedness checking.
7273
if let ObligationCauseCode::WellFormed(Some(wf_loc)) =
@@ -81,6 +82,12 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
8182
span = obligation.cause.span;
8283
}
8384
}
85+
if let ObligationCauseCode::SizedConstOrStatic | ObligationCauseCode::SharedStatic = root_obligation.cause.code() {
86+
let node = tcx.hir_node_by_def_id(root_obligation.cause.body_id);
87+
span = node.ty().unwrap_or_else(|| panic!("{node:?} had no type")).span;
88+
obligation.cause.span = span;
89+
trace!("patched up span")
90+
}
8491

8592
if let ObligationCauseCode::CompareImplItem {
8693
impl_item_def_id,

0 commit comments

Comments
 (0)