Don't look at static items' HIR for wfcheck
This commit is contained in:
parent
9b5d57d0a9
commit
362d4ddff4
14 changed files with 67 additions and 77 deletions
|
|
@ -4862,6 +4862,10 @@ impl<'hir> Node<'hir> {
|
|||
ImplItemKind::Type(ty) => Some(ty),
|
||||
_ => None,
|
||||
},
|
||||
Node::ForeignItem(it) => match it.kind {
|
||||
ForeignItemKind::Static(ty, ..) => Some(ty),
|
||||
_ => None,
|
||||
},
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -729,7 +729,7 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||
let generics = tcx.generics_of(def_id);
|
||||
|
||||
for param in &generics.own_params {
|
||||
|
|
@ -757,6 +757,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
DefKind::Static { .. } => {
|
||||
check_static_inhabited(tcx, def_id);
|
||||
check_static_linkage(tcx, def_id);
|
||||
wfcheck::check_static_item(tcx, def_id)?;
|
||||
}
|
||||
DefKind::Const => {}
|
||||
DefKind::Enum => {
|
||||
|
|
@ -774,13 +775,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
}
|
||||
DefKind::Impl { of_trait } => {
|
||||
if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
|
||||
if tcx
|
||||
.ensure_ok()
|
||||
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)
|
||||
.is_ok()
|
||||
{
|
||||
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
|
||||
}
|
||||
tcx.ensure_ok()
|
||||
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)?;
|
||||
|
||||
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
|
||||
}
|
||||
}
|
||||
DefKind::Trait => {
|
||||
|
|
@ -838,7 +836,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
DefKind::ForeignMod => {
|
||||
let it = tcx.hir_expect_item(def_id);
|
||||
let hir::ItemKind::ForeignMod { abi, items } = it.kind else {
|
||||
return;
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
check_abi(tcx, it.hir_id(), it.span, abi);
|
||||
|
|
@ -896,6 +894,7 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||
}
|
||||
_ => {}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(super) fn check_on_unimplemented(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
||||
|
|
|
|||
|
|
@ -185,9 +185,9 @@ where
|
|||
}
|
||||
|
||||
fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
|
||||
crate::check::check::check_item_type(tcx, def_id);
|
||||
let mut res = crate::check::check::check_item_type(tcx, def_id);
|
||||
let node = tcx.hir_node_by_def_id(def_id);
|
||||
let mut res = match node {
|
||||
res = res.and(match node {
|
||||
hir::Node::Crate(_) => bug!("check_well_formed cannot be applied to the crate root"),
|
||||
hir::Node::Item(item) => check_item(tcx, item),
|
||||
hir::Node::TraitItem(item) => check_trait_item(tcx, item),
|
||||
|
|
@ -195,7 +195,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
|
|||
hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
|
||||
hir::Node::ConstBlock(_) | hir::Node::Expr(_) | hir::Node::OpaqueTy(_) => Ok(()),
|
||||
_ => unreachable!("{node:?}"),
|
||||
};
|
||||
});
|
||||
|
||||
for param in &tcx.generics_of(def_id).own_params {
|
||||
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<()
|
|||
res
|
||||
}
|
||||
hir::ItemKind::Fn { ident, sig, .. } => check_item_fn(tcx, def_id, ident, sig.decl),
|
||||
hir::ItemKind::Static(_, _, ty, _) => {
|
||||
check_static_item(tcx, def_id, ty.span, UnsizedHandling::Forbid)
|
||||
}
|
||||
hir::ItemKind::Const(_, _, ty, _) => check_const_item(tcx, def_id, ty.span, item.span),
|
||||
hir::ItemKind::Struct(_, generics, _) => {
|
||||
let res = check_type_defn(tcx, item, false);
|
||||
|
|
@ -347,10 +344,7 @@ fn check_foreign_item<'tcx>(
|
|||
|
||||
match item.kind {
|
||||
hir::ForeignItemKind::Fn(sig, ..) => check_item_fn(tcx, def_id, item.ident, sig.decl),
|
||||
hir::ForeignItemKind::Static(ty, ..) => {
|
||||
check_static_item(tcx, def_id, ty.span, UnsizedHandling::AllowIfForeignTail)
|
||||
}
|
||||
hir::ForeignItemKind::Type => Ok(()),
|
||||
hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => Ok(()),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1251,61 +1245,54 @@ fn check_item_fn(
|
|||
})
|
||||
}
|
||||
|
||||
enum UnsizedHandling {
|
||||
Forbid,
|
||||
AllowIfForeignTail,
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(tcx, ty_span, unsized_handling))]
|
||||
fn check_static_item(
|
||||
#[instrument(level = "debug", skip(tcx))]
|
||||
pub(super) fn check_static_item(
|
||||
tcx: TyCtxt<'_>,
|
||||
item_id: LocalDefId,
|
||||
ty_span: Span,
|
||||
unsized_handling: UnsizedHandling,
|
||||
) -> Result<(), ErrorGuaranteed> {
|
||||
enter_wf_checking_ctxt(tcx, item_id, |wfcx| {
|
||||
let ty = tcx.type_of(item_id).instantiate_identity();
|
||||
let item_ty = wfcx.deeply_normalize(ty_span, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
let item_ty = wfcx.deeply_normalize(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), ty);
|
||||
|
||||
let forbid_unsized = match unsized_handling {
|
||||
UnsizedHandling::Forbid => true,
|
||||
UnsizedHandling::AllowIfForeignTail => {
|
||||
let tail =
|
||||
tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
|
||||
!matches!(tail.kind(), ty::Foreign(_))
|
||||
}
|
||||
let is_foreign_item = tcx.is_foreign_item(item_id);
|
||||
|
||||
let forbid_unsized = !is_foreign_item || {
|
||||
let tail = tcx.struct_tail_for_codegen(item_ty, wfcx.infcx.typing_env(wfcx.param_env));
|
||||
!matches!(tail.kind(), ty::Foreign(_))
|
||||
};
|
||||
|
||||
wfcx.register_wf_obligation(ty_span, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
|
||||
wfcx.register_wf_obligation(DUMMY_SP, Some(WellFormedLoc::Ty(item_id)), item_ty.into());
|
||||
if forbid_unsized {
|
||||
let span = tcx.def_span(item_id);
|
||||
wfcx.register_bound(
|
||||
traits::ObligationCause::new(
|
||||
ty_span,
|
||||
span,
|
||||
wfcx.body_def_id,
|
||||
ObligationCauseCode::SizedConstOrStatic,
|
||||
),
|
||||
wfcx.param_env,
|
||||
item_ty,
|
||||
tcx.require_lang_item(LangItem::Sized, ty_span),
|
||||
tcx.require_lang_item(LangItem::Sized, span),
|
||||
);
|
||||
}
|
||||
|
||||
// Ensure that the end result is `Sync` in a non-thread local `static`.
|
||||
let should_check_for_sync = tcx.static_mutability(item_id.to_def_id())
|
||||
== Some(hir::Mutability::Not)
|
||||
&& !tcx.is_foreign_item(item_id.to_def_id())
|
||||
&& !is_foreign_item
|
||||
&& !tcx.is_thread_local_static(item_id.to_def_id());
|
||||
|
||||
if should_check_for_sync {
|
||||
let span = tcx.def_span(item_id);
|
||||
wfcx.register_bound(
|
||||
traits::ObligationCause::new(
|
||||
ty_span,
|
||||
span,
|
||||
wfcx.body_def_id,
|
||||
ObligationCauseCode::SharedStatic,
|
||||
),
|
||||
wfcx.param_env,
|
||||
item_ty,
|
||||
tcx.require_lang_item(LangItem::Sync, ty_span),
|
||||
tcx.require_lang_item(LangItem::Sync, span),
|
||||
);
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -17,19 +17,19 @@ LL | const CONST_FOO: str = *"foo";
|
|||
= note: statics and constants must have a statically known size
|
||||
|
||||
error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
|
||||
--> $DIR/const-unsized.rs:11:18
|
||||
--> $DIR/const-unsized.rs:11:1
|
||||
|
|
||||
LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
|
||||
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
||||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/const-unsized.rs:15:20
|
||||
--> $DIR/const-unsized.rs:15:1
|
||||
|
|
||||
LL | static STATIC_BAR: str = *"bar";
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
|
|
|||
|
|
@ -24,10 +24,10 @@ LL | static FOO: dyn Sync = AtomicUsize::new(0);
|
|||
| +++
|
||||
|
||||
error[E0277]: the size for values of type `(dyn Sync + 'static)` cannot be known at compilation time
|
||||
--> $DIR/const_refs_to_static-ice-121413.rs:8:17
|
||||
--> $DIR/const_refs_to_static-ice-121413.rs:8:5
|
||||
|
|
||||
LL | static FOO: Sync = AtomicUsize::new(0);
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/dont-ctfe-unsized-initializer.rs:1:11
|
||||
--> $DIR/dont-ctfe-unsized-initializer.rs:1:1
|
||||
|
|
||||
LL | static S: str = todo!();
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `str`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the size for values of type `[usize]` cannot be known at compilation time
|
||||
--> $DIR/issue-36122-accessing-externed-dst.rs:3:24
|
||||
--> $DIR/issue-36122-accessing-externed-dst.rs:3:9
|
||||
|
|
||||
LL | static symbol: [usize];
|
||||
| ^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[usize]`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the size for values of type `[i8]` cannot be known at compilation time
|
||||
--> $DIR/issue-54410.rs:2:28
|
||||
--> $DIR/issue-54410.rs:2:5
|
||||
|
|
||||
LL | pub static mut symbol: [i8];
|
||||
| ^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[i8]`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: `RefCell<isize>` cannot be shared between threads safely
|
||||
--> $DIR/issue-7364.rs:4:15
|
||||
--> $DIR/issue-7364.rs:4:1
|
||||
|
|
||||
LL | static boxed: Box<RefCell<isize>> = Box::new(RefCell::new(0));
|
||||
| ^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `RefCell<isize>` cannot be shared between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `RefCell<isize>`
|
||||
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
|
||||
|
|
|
|||
|
|
@ -1,17 +1,17 @@
|
|||
error[E0277]: `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
|
||||
--> $DIR/issue-24446.rs:2:17
|
||||
--> $DIR/issue-24446.rs:2:5
|
||||
|
|
||||
LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
||||
| ^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Fn() -> u32 + 'static)` cannot be shared between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `(dyn Fn() -> u32 + 'static)`
|
||||
= note: shared static variables must have a type that implements `Sync`
|
||||
|
||||
error[E0277]: the size for values of type `(dyn Fn() -> u32 + 'static)` cannot be known at compilation time
|
||||
--> $DIR/issue-24446.rs:2:17
|
||||
--> $DIR/issue-24446.rs:2:5
|
||||
|
|
||||
LL | static foo: dyn Fn() -> u32 = || -> u32 {
|
||||
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
|
||||
= note: statics and constants must have a statically known size
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: `Foo` cannot be shared between threads safely
|
||||
--> $DIR/issue-17718-static-sync.rs:9:13
|
||||
--> $DIR/issue-17718-static-sync.rs:9:1
|
||||
|
|
||||
LL | static BAR: Foo = Foo;
|
||||
| ^^^ `Foo` cannot be shared between threads safely
|
||||
| ^^^^^^^^^^^^^^^ `Foo` cannot be shared between threads safely
|
||||
|
|
||||
= help: the trait `Sync` is not implemented for `Foo`
|
||||
= note: shared static variables must have a type that implements `Sync`
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
error[E0277]: the size for values of type `str` cannot be known at compilation time
|
||||
--> $DIR/unsized_type2.rs:14:24
|
||||
--> $DIR/unsized_type2.rs:14:1
|
||||
|
|
||||
LL | pub static WITH_ERROR: Foo = Foo { version: 0 };
|
||||
| ^^^ doesn't have a size known at compile-time
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
= help: within `Foo`, the trait `Sized` is not implemented for `str`
|
||||
note: required because it appears within the type `Foo`
|
||||
|
|
|
|||
|
|
@ -22,10 +22,10 @@ LL | fn bar() -> i32 where Self: Sized;
|
|||
| +++++++++++++++++
|
||||
|
||||
error[E0277]: `(dyn Qux + 'static)` cannot be shared between threads safely
|
||||
--> $DIR/unsizing-wfcheck-issue-127299.rs:12:13
|
||||
--> $DIR/unsizing-wfcheck-issue-127299.rs:12:1
|
||||
|
|
||||
LL | static FOO: &Lint = &Lint { desc: "desc" };
|
||||
| ^^^^^ `(dyn Qux + 'static)` cannot be shared between threads safely
|
||||
| ^^^^^^^^^^^^^^^^^ `(dyn Qux + 'static)` cannot be shared between threads safely
|
||||
|
|
||||
= help: within `&'static Lint`, the trait `Sync` is not implemented for `(dyn Qux + 'static)`
|
||||
= note: required because it appears within the type `&'static (dyn Qux + 'static)`
|
||||
|
|
|
|||
|
|
@ -35,6 +35,17 @@ error[E0207]: the type parameter `U` is not constrained by the impl trait, self
|
|||
LL | impl<T, U> Foo<T> for [isize; 1] {
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Bar`
|
||||
--> $DIR/constrained-type-params-trait-impl.rs:48:1
|
||||
|
|
||||
LL | impl<T, U> Bar for T {
|
||||
| -------------------- first implementation here
|
||||
...
|
||||
LL | / impl<T, U> Bar for T
|
||||
LL | | where
|
||||
LL | | T: Bar<Out = U>,
|
||||
| |____________________^ conflicting implementation
|
||||
|
||||
error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
|
||||
--> $DIR/constrained-type-params-trait-impl.rs:42:9
|
||||
|
|
||||
|
|
@ -59,17 +70,6 @@ error[E0207]: the type parameter `V` is not constrained by the impl trait, self
|
|||
LL | impl<T, U, V> Foo<T> for T
|
||||
| ^ unconstrained type parameter
|
||||
|
||||
error[E0119]: conflicting implementations of trait `Bar`
|
||||
--> $DIR/constrained-type-params-trait-impl.rs:48:1
|
||||
|
|
||||
LL | impl<T, U> Bar for T {
|
||||
| -------------------- first implementation here
|
||||
...
|
||||
LL | / impl<T, U> Bar for T
|
||||
LL | | where
|
||||
LL | | T: Bar<Out = U>,
|
||||
| |____________________^ conflicting implementation
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0119, E0207.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue