Skip to content

Commit 362d4dd

Browse files
committed
Don't look at static items' HIR for wfcheck
1 parent 9b5d57d commit 362d4dd

14 files changed

+68
-78
lines changed

compiler/rustc_hir/src/hir.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4862,6 +4862,10 @@ impl<'hir> Node<'hir> {
48624862
ImplItemKind::Type(ty) => Some(ty),
48634863
_ => None,
48644864
},
4865+
Node::ForeignItem(it) => match it.kind {
4866+
ForeignItemKind::Static(ty, ..) => Some(ty),
4867+
_ => None,
4868+
},
48654869
_ => None,
48664870
}
48674871
}

compiler/rustc_hir_analysis/src/check/check.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
729729
}
730730
}
731731

732-
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
732+
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
733733
let generics = tcx.generics_of(def_id);
734734

735735
for param in &generics.own_params {
@@ -757,6 +757,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
757757
DefKind::Static { .. } => {
758758
check_static_inhabited(tcx, def_id);
759759
check_static_linkage(tcx, def_id);
760+
wfcheck::check_static_item(tcx, def_id)?;
760761
}
761762
DefKind::Const => {}
762763
DefKind::Enum => {
@@ -774,13 +775,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
774775
}
775776
DefKind::Impl { of_trait } => {
776777
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
777-
if tcx
778-
.ensure_ok()
779-
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
780-
.is_ok()
781-
{
782-
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
783-
}
778+
tcx.ensure_ok()
779+
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)?;
780+
781+
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
784782
}
785783
}
786784
DefKind::Trait => {
@@ -838,7 +836,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
838836
DefKind::ForeignMod => {
839837
let it = tcx.hir_expect_item(def_id);
840838
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
841-
return;
839+
return Ok(());
842840
};
843841

844842
check_abi(tcx, it.hir_id(), it.span, abi);
@@ -896,6 +894,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
896894
}
897895
_ => {}
898896
}
897+
Ok(())
899898
}
900899

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

compiler/rustc_hir_analysis/src/check/wfcheck.rs

Lines changed: 21 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -185,17 +185,17 @@ where
185185
}
186186

187187
fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
188-
crate::check::check::check_item_type(tcx, def_id);
188+
let mut res = crate::check::check::check_item_type(tcx, def_id);
189189
let node = tcx.hir_node_by_def_id(def_id);
190-
let mut res = match node {
190+
res = res.and(match node {
191191
hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
192192
hir::Node::Item(item) => check_item(tcx, item),
193193
hir::Node::TraitItem(item) => check_trait_item(tcx, item),
194194
hir::Node::ImplItem(item) => check_impl_item(tcx, item),
195195
hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
196196
hir::Node::ConstBlock(_) | hir::Node::Expr(_) | hir::Node::OpaqueTy(_) => Ok(()),
197197
_ => unreachable!("{node:?}"),
198-
};
198+
});
199199

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

348345
match item.kind {
349346
hir::ForeignItemKind::Fn(sig, ..) => check_item_fn(tcx, def_id, item.ident, sig.decl),
350-
hir::ForeignItemKind::Static(ty, ..) => {
351-
check_static_item(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
352-
}
353-
hir::ForeignItemKind::Type => Ok(()),
347+
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => Ok(()),
354348
}
355349
}
356350

@@ -1251,61 +1245,54 @@ fn check_item_fn(
12511245
})
12521246
}
12531247

1254-
enum UnsizedHandling {
1255-
Forbid,
1256-
AllowIfForeignTail,
1257-
}
1258-
1259-
#[instrument(level = "debug", skip(tcx, ty_span, unsized_handling))]
1260-
fn check_static_item(
1248+
#[instrument(level = "debug", skip(tcx))]
1249+
pub(super) fn check_static_item(
12611250
tcx: TyCtxt<'_>,
12621251
item_id: LocalDefId,
1263-
ty_span: Span,
1264-
unsized_handling: UnsizedHandling,
12651252
) -> Result<(), ErrorGuaranteed> {
12661253
enter_wf_checking_ctxt(tcx, item_id, |wfcx| {
12671254
let ty = tcx.type_of(item_id).instantiate_identity();
1268-
let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
1269-
1270-
let forbid_unsized = match unsized_handling {
1271-
UnsizedHandling::Forbid => true,
1272-
UnsizedHandling::AllowIfForeignTail => {
1273-
let tail =
1274-
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
1275-
!matches!(tail.kind(), ty::Foreign(_))
1276-
}
1255+
let item_ty = wfcx.deeply_normalize(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), ty);
1256+
1257+
let is_foreign_item = tcx.is_foreign_item(item_id);
1258+
1259+
let forbid_unsized = !is_foreign_item || {
1260+
let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
1261+
!matches!(tail.kind(), ty::Foreign(_))
12771262
};
12781263

1279-
wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
1264+
wfcx.register_wf_obligation(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
12801265
if forbid_unsized {
1266+
let span = tcx.def_span(item_id);
12811267
wfcx.register_bound(
12821268
traits::ObligationCause::new(
1283-
ty_span,
1269+
span,
12841270
wfcx.body_def_id,
12851271
ObligationCauseCode::SizedConstOrStatic,
12861272
),
12871273
wfcx.param_env,
12881274
item_ty,
1289-
tcx.require_lang_item(LangItem::Sized, ty_span),
1275+
tcx.require_lang_item(LangItem::Sized, span),
12901276
);
12911277
}
12921278

12931279
// Ensure that the end result is `Sync` in a non-thread local `static`.
12941280
let should_check_for_sync = tcx.static_mutability(item_id.to_def_id())
12951281
== Some(hir::Mutability::Not)
1296-
&& !tcx.is_foreign_item(item_id.to_def_id())
1282+
&& !is_foreign_item
12971283
&& !tcx.is_thread_local_static(item_id.to_def_id());
12981284

12991285
if should_check_for_sync {
1286+
let span = tcx.def_span(item_id);
13001287
wfcx.register_bound(
13011288
traits::ObligationCause::new(
1302-
ty_span,
1289+
span,
13031290
wfcx.body_def_id,
13041291
ObligationCauseCode::SharedStatic,
13051292
),
13061293
wfcx.param_env,
13071294
item_ty,
1308-
tcx.require_lang_item(LangItem::Sync, ty_span),
1295+
tcx.require_lang_item(LangItem::Sync, span),
13091296
);
13101297
}
13111298
Ok(())

tests/ui/consts/const-unsized.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@ LL | const CONST_FOO: str = *"foo";
1717
= note: statics and constants must have a statically known size
1818

1919
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
20-
--> $DIR/const-unsized.rs:11:18
20+
--> $DIR/const-unsized.rs:11:1
2121
|
2222
LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
23-
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
23+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
2424
|
2525
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
2626
= note: statics and constants must have a statically known size
2727

2828
error[E0277]: the size for values of type `str` cannot be known at compilation time
29-
--> $DIR/const-unsized.rs:15:20
29+
--> $DIR/const-unsized.rs:15:1
3030
|
3131
LL | static STATIC_BAR: str = *"bar";
32-
| ^^^ doesn't have a size known at compile-time
32+
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
3333
|
3434
= help: the trait `Sized` is not implemented for `str`
3535
= note: statics and constants must have a statically known size

tests/ui/consts/const_refs_to_static-ice-121413.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ LL | static FOO: dyn Sync = AtomicUsize::new(0);
2424
| +++
2525

2626
error[E0277]: the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
27-
--> $DIR/const_refs_to_static-ice-121413.rs:8:17
27+
--> $DIR/const_refs_to_static-ice-121413.rs:8:5
2828
|
2929
LL | static FOO: Sync = AtomicUsize::new(0);
30-
| ^^^^ doesn't have a size known at compile-time
30+
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
3131
|
3232
= help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
3333
= note: statics and constants must have a statically known size

tests/ui/consts/dont-ctfe-unsized-initializer.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the size for values of type `str` cannot be known at compilation time
2-
--> $DIR/dont-ctfe-unsized-initializer.rs:1:11
2+
--> $DIR/dont-ctfe-unsized-initializer.rs:1:1
33
|
44
LL | static S: str = todo!();
5-
| ^^^ doesn't have a size known at compile-time
5+
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `Sized` is not implemented for `str`
88
= note: statics and constants must have a statically known size

tests/ui/extern/issue-36122-accessing-externed-dst.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
2-
--> $DIR/issue-36122-accessing-externed-dst.rs:3:24
2+
--> $DIR/issue-36122-accessing-externed-dst.rs:3:9
33
|
44
LL | static symbol: [usize];
5-
| ^^^^^^^ doesn't have a size known at compile-time
5+
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `Sized` is not implemented for `[usize]`
88
= note: statics and constants must have a statically known size

tests/ui/issues/issue-54410.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
2-
--> $DIR/issue-54410.rs:2:28
2+
--> $DIR/issue-54410.rs:2:5
33
|
44
LL | pub static mut symbol: [i8];
5-
| ^^^^ doesn't have a size known at compile-time
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
66
|
77
= help: the trait `Sized` is not implemented for `[i8]`
88
= note: statics and constants must have a statically known size

tests/ui/issues/issue-7364.stderr

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0277]: `RefCell<isize>` cannot be shared between threads safely
2-
--> $DIR/issue-7364.rs:4:15
2+
--> $DIR/issue-7364.rs:4:1
33
|
44
LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
5-
| ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
66
|
77
= help: the trait `Sync` is not implemented for `RefCell<isize>`
88
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead

tests/ui/static/issue-24446.stderr

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
error[E0277]: `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
2-
--> $DIR/issue-24446.rs:2:17
2+
--> $DIR/issue-24446.rs:2:5
33
|
44
LL | static foo: dyn Fn() -> u32 = || -> u32 {
5-
| ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
66
|
77
= help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)`
88
= note: shared static variables must have a type that implements `Sync`
99

1010
error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot be known at compilation time
11-
--> $DIR/issue-24446.rs:2:17
11+
--> $DIR/issue-24446.rs:2:5
1212
|
1313
LL | static foo: dyn Fn() -> u32 = || -> u32 {
14-
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
14+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
1515
|
1616
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
1717
= note: statics and constants must have a statically known size

0 commit comments

Comments
 (0)