Skip to content

Commit 2a676f2

Browse files
Auto merge of #142030 - oli-obk:wfck-less-hir, r=<try>
Start moving wf checking away from HIR I'm trying to only access the HIR in the error path. My hope is that once we move significant portions of wfcheck off HIR that incremental will be able to cache wfcheck queries significantly better. I think I am reaching a blocker because we normally need to provide good spans to `ObligationCause`, so that the trait solver can report good errors. In some cases I have been able to use bad spans and improve them depending on the `ObligationCauseCode` (by loading HIR in the case where we actually want to error). To scale that further we'll likely need to remove spans from the `ObligationCause` entirely (leaving it to some variants of `ObligationCauseCode` to have a span when they can't recompute the information later). Unsure this is the right approach, but we've already been using it. I will create an MCP about it, but that should not affect this PR, which is fairly limited in where it does those kind of tricks. Especially b862d88 is interesting here, because I think it improves spans in all cases
2 parents 61413ae + e38ae45 commit 2a676f2

File tree

88 files changed

+943
-770
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+943
-770
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: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_errors::codes::*;
99
use rustc_hir::def::{CtorKind, DefKind};
1010
use rustc_hir::{LangItem, Node, intravisit};
1111
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
12-
use rustc_infer::traits::{Obligation, ObligationCauseCode};
12+
use rustc_infer::traits::{Obligation, ObligationCauseCode, WellFormedLoc};
1313
use rustc_lint_defs::builtin::{
1414
REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS, UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
1515
};
@@ -34,6 +34,9 @@ use {rustc_attr_data_structures as attrs, rustc_hir as hir};
3434

3535
use super::compare_impl_item::check_type_bounds;
3636
use super::*;
37+
use crate::check::wfcheck::{
38+
check_variances_for_type_defn, check_where_clauses, enter_wf_checking_ctxt,
39+
};
3740

3841
pub fn check_abi(tcx: TyCtxt<'_>, span: Span, abi: ExternAbi) {
3942
if !tcx.sess.target.is_abi_supported(abi) {
@@ -701,15 +704,18 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
701704
}
702705
}
703706

704-
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
707+
pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGuaranteed> {
708+
let mut res = Ok(());
705709
match tcx.def_kind(def_id) {
706710
DefKind::Static { .. } => {
707711
check_static_inhabited(tcx, def_id);
708712
check_static_linkage(tcx, def_id);
713+
wfcheck::check_static_item(tcx, def_id)?;
709714
}
710715
DefKind::Const => {}
711716
DefKind::Enum => {
712717
check_enum(tcx, def_id);
718+
check_variances_for_type_defn(tcx, def_id);
713719
}
714720
DefKind::Fn => {
715721
if let Some(i) = tcx.intrinsic(def_id) {
@@ -723,13 +729,10 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
723729
}
724730
DefKind::Impl { of_trait } => {
725731
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-
}
732+
tcx.ensure_ok()
733+
.coherent_trait(impl_trait_header.trait_ref.instantiate_identity().def_id)?;
734+
735+
check_impl_items_against_trait(tcx, def_id, impl_trait_header);
733736
}
734737
}
735738
DefKind::Trait => {
@@ -753,9 +756,11 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
753756
}
754757
DefKind::Struct => {
755758
check_struct(tcx, def_id);
759+
check_variances_for_type_defn(tcx, def_id);
756760
}
757761
DefKind::Union => {
758762
check_union(tcx, def_id);
763+
check_variances_for_type_defn(tcx, def_id);
759764
}
760765
DefKind::OpaqueTy => {
761766
check_opaque_precise_captures(tcx, def_id);
@@ -773,13 +778,25 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
773778
}
774779
DefKind::TyAlias => {
775780
check_type_alias_type_params_are_used(tcx, def_id);
781+
if tcx.type_alias_is_lazy(def_id) {
782+
res = res.and(enter_wf_checking_ctxt(tcx, def_id, |wfcx| {
783+
let ty = tcx.type_of(def_id).instantiate_identity();
784+
let span = tcx.def_span(def_id);
785+
let item_ty = wfcx.deeply_normalize(span, Some(WellFormedLoc::Ty(def_id)), ty);
786+
wfcx.register_wf_obligation(
787+
span,
788+
Some(WellFormedLoc::Ty(def_id)),
789+
item_ty.into(),
790+
);
791+
check_where_clauses(wfcx, def_id);
792+
Ok(())
793+
}));
794+
check_variances_for_type_defn(tcx, def_id);
795+
}
776796
}
777797
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);
798+
let (abi, items) = tcx.hir_expect_item(def_id).expect_foreign_mod();
799+
check_abi(tcx, tcx.def_span(def_id), abi);
783800

784801
for item in items {
785802
let def_id = item.id.owner_id.def_id;
@@ -819,16 +836,13 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
819836
hir::ForeignItemKind::Fn(sig, _, _) => {
820837
require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
821838
}
822-
hir::ForeignItemKind::Static(..) => {
823-
check_static_inhabited(tcx, def_id);
824-
check_static_linkage(tcx, def_id);
825-
}
826839
_ => {}
827840
}
828841
}
829842
}
830843
_ => {}
831844
}
845+
res
832846
}
833847

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

0 commit comments

Comments
 (0)