1
Fork 0

Rollup merge of #131856 - lcnr:typing-mode, r=compiler-errors

TypingMode: merge intercrate, reveal, and defining_opaque_types

This adds `TypingMode` and uses it in most places. We do not yet remove `Reveal` from `param_env`s. This and other future work as tracked in #132279 and via `FIXME`s.

Fetching the `TypingMode` of the `InferCtxt` asserts that the `TypingMode` agrees with `ParamEnv::reveal` to make sure we don't introduce any subtle bugs here. This will be unnecessary once `ParamEnv::reveal` no longer exists.

As the `TypingMode` is now a part of the query input, I've merged the coherence and non-coherence caches for the new solver. I've also enabled the local `infcx` cache during coherence by clearing the cache when forking it with a different `TypingMode`.

#### `TypingMode::from_param_env`

I am using this even in cases where I know that the `param_env` will always be `Reveal::UserFacing`. This is to make it easier to correctly refactor this code in the future, any time we use `Reveal::UserFacing` in a body while not defining its opaque types is incorrect and should use a `TypingMode` which only reveals opaques defined by that body instead, cc #124598

r? ``@compiler-errors``
This commit is contained in:
Matthias Krüger 2024-10-30 06:40:34 +01:00 committed by GitHub
commit 305508f969
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
89 changed files with 537 additions and 532 deletions

View file

@ -31,7 +31,7 @@ use rustc_middle::bug;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::layout::LayoutOf;
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, Upcast, VariantDef};
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, Upcast, VariantDef};
use rustc_session::lint::FutureIncompatibilityReason;
// hardwired lints from rustc_lint_defs
pub use rustc_session::lint::builtin::*;
@ -604,7 +604,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingCopyImplementations {
&& cx
.tcx
.infer_ctxt()
.build()
.build(cx.typing_mode())
.type_implements_trait(iter_trait, [ty], cx.param_env)
.must_apply_modulo_regions()
{
@ -648,7 +648,9 @@ fn type_implements_negative_copy_modulo_regions<'tcx>(
predicate: pred.upcast(tcx),
};
tcx.infer_ctxt().build().predicate_must_hold_modulo_regions(&obligation)
tcx.infer_ctxt()
.build(TypingMode::non_body_analysis())
.predicate_must_hold_modulo_regions(&obligation)
}
declare_lint! {

View file

@ -14,11 +14,12 @@ use rustc_feature::Features;
use rustc_hir::def::Res;
use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_infer::traits::Reveal;
use rustc_middle::bug;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingMode};
use rustc_session::lint::{
BuiltinLintDiag, FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
};
@ -698,6 +699,15 @@ impl LintContext for EarlyContext<'_> {
}
impl<'tcx> LateContext<'tcx> {
/// The typing mode of the currently visited node. Use this when
/// building a new `InferCtxt`.
pub fn typing_mode(&self) -> TypingMode<'tcx> {
debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
// FIXME(#132279): In case we're in a body, we should use a typing
// mode which reveals the opaque types defined by that body.
TypingMode::non_body_analysis()
}
/// Gets the type-checking results for the current body,
/// or `None` if outside a body.
pub fn maybe_typeck_results(&self) -> Option<&'tcx ty::TypeckResults<'tcx>> {

View file

@ -166,7 +166,7 @@ fn suggest_question_mark<'tcx>(
}
let ty = args.type_at(0);
let infcx = cx.tcx.infer_ctxt().build();
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
let ocx = ObligationCtxt::new(&infcx);
let body_def_id = cx.tcx.hir().body_owner_def_id(body_id);

View file

@ -15,7 +15,7 @@ use rustc_middle::ty::relate::{
Relate, RelateResult, TypeRelation, structurally_relate_consts, structurally_relate_tys,
};
use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor, TypingMode,
};
use rustc_middle::{bug, span_bug};
use rustc_session::lint::FutureIncompatibilityReason;
@ -184,7 +184,7 @@ fn check_fn(tcx: TyCtxt<'_>, parent_def_id: LocalDefId) {
}),
outlives_env: LazyCell::new(|| {
let param_env = tcx.param_env(parent_def_id);
let infcx = tcx.infer_ctxt().build();
let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
let ocx = ObligationCtxt::new(&infcx);
let assumed_wf_tys = ocx.assumed_wf_types(param_env, parent_def_id).unwrap_or_default();
let implied_bounds =

View file

@ -157,7 +157,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
Some(ty_def) if cx.tcx.is_lang_item(ty_def.did(), LangItem::String),
);
let infcx = cx.tcx.infer_ctxt().build();
let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
let suggest_display = is_str
|| cx.tcx.get_diagnostic_item(sym::Display).is_some_and(|t| {
infcx.type_implements_trait(t, [ty], cx.param_env).may_apply()

View file

@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
}
let def_id = opaque.def_id.to_def_id();
let infcx = &cx.tcx.infer_ctxt().build();
let infcx = &cx.tcx.infer_ctxt().build(cx.typing_mode());
// For every projection predicate in the opaque type's explicit bounds,
// check that the type that we're assigning actually satisfies the bounds
// of the associated type.