thir building: use typing_env directly

This commit is contained in:
lcnr 2024-11-22 12:17:50 +01:00
parent 0f8405f702
commit f4b516b10c
5 changed files with 32 additions and 67 deletions

View File

@ -595,7 +595,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo
}
if let ty::Ref(_, sub_ty, _) = self.ty.kind() {
if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env()) {
if !sub_ty.is_inhabited_from(self.cx.tcx, self.cx.module, self.cx.typing_env) {
diag.note(fluent::mir_build_reference_note);
}
}

View File

@ -284,7 +284,7 @@ impl<'tcx> Cx<'tcx> {
let discr_ty = ty.to_ty(tcx);
let size = tcx
.layout_of(self.typing_env().as_query_input(discr_ty))
.layout_of(self.typing_env.as_query_input(discr_ty))
.unwrap_or_else(|e| panic!("could not compute layout for {discr_ty:?}: {e:?}"))
.size;
@ -1040,7 +1040,7 @@ impl<'tcx> Cx<'tcx> {
// but distinguish between &STATIC and &THREAD_LOCAL as they have different semantics
Res::Def(DefKind::Static { .. }, id) => {
// this is &raw for extern static or static mut, and & for other statics
let ty = self.tcx.static_ptr_ty(id, self.typing_env());
let ty = self.tcx.static_ptr_ty(id, self.typing_env);
let (temp_lifetime, backwards_incompatible) = self
.rvalue_scopes
.temporary_scope(self.region_scope_tree, expr.hir_id.local_id);

View File

@ -12,7 +12,6 @@ use rustc_hir::lang_items::LangItem;
use rustc_middle::bug;
use rustc_middle::middle::region;
use rustc_middle::thir::*;
use rustc_middle::ty::solve::Reveal;
use rustc_middle::ty::{self, RvalueScopes, TyCtxt};
use tracing::instrument;
@ -57,7 +56,7 @@ struct Cx<'tcx> {
tcx: TyCtxt<'tcx>,
thir: Thir<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
region_scope_tree: &'tcx region::ScopeTree,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
@ -98,7 +97,9 @@ impl<'tcx> Cx<'tcx> {
Cx {
tcx,
thir: Thir::new(body_type),
param_env: tcx.param_env(def),
// FIXME(#132279): We're in a body, we should use a typing
// mode which reveals the opaque types defined by that body.
typing_env: ty::TypingEnv::non_body_analysis(tcx, def),
region_scope_tree: tcx.region_scope_tree(def),
typeck_results,
rvalue_scopes: &typeck_results.rvalue_scopes,
@ -110,20 +111,9 @@ impl<'tcx> Cx<'tcx> {
}
}
fn typing_mode(&self) -> ty::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.
ty::TypingMode::non_body_analysis()
}
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
}
#[instrument(level = "debug", skip(self))]
fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
pat_from_hir(self.tcx, self.typing_env(), self.typeck_results(), p)
pat_from_hir(self.tcx, self.typing_env, self.typeck_results(), p)
}
fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {

View File

@ -8,7 +8,6 @@ use rustc_hir::def::*;
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{self as hir, BindingMode, ByRef, HirId};
use rustc_infer::infer::TyCtxtInferExt;
use rustc_infer::traits::Reveal;
use rustc_lint::Level;
use rustc_middle::bug;
use rustc_middle::middle::limits::get_limit_size;
@ -43,7 +42,8 @@ pub(crate) fn check_match(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), Err
tcx,
thir: &*thir,
typeck_results,
param_env: tcx.param_env(def_id),
// FIXME(#132279): We're in a body, should handle opaques.
typing_env: ty::TypingEnv::non_body_analysis(tcx, def_id),
lint_level: tcx.local_def_id_to_hir_id(def_id),
let_source: LetSource::None,
pattern_arena: &pattern_arena,
@ -90,7 +90,7 @@ enum LetSource {
struct MatchVisitor<'p, 'tcx> {
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
typing_env: ty::TypingEnv<'tcx>,
typeck_results: &'tcx ty::TypeckResults<'tcx>,
thir: &'p Thir<'tcx>,
lint_level: HirId,
@ -196,15 +196,6 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
}
impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
// FIXME(#132279): We're in a body, should handle opaques.
debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
ty::TypingEnv {
typing_mode: ty::TypingMode::non_body_analysis(),
param_env: self.param_env,
}
}
#[instrument(level = "trace", skip(self, f))]
fn with_let_source(&mut self, let_source: LetSource, f: impl FnOnce(&mut Self)) {
let old_let_source = self.let_source;
@ -395,7 +386,7 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
PatCtxt {
tcx: self.tcx,
typeck_results: self.typeck_results,
param_env: self.param_env,
typing_env: self.typing_env,
module: self.tcx.parent_module(self.lint_level).to_def_id(),
dropless_arena: self.dropless_arena,
match_lint_level: self.lint_level,
@ -749,8 +740,8 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
.variant(*variant_index)
.inhabited_predicate(self.tcx, *adt)
.instantiate(self.tcx, args);
variant_inhabited.apply(self.tcx, cx.typing_env(), cx.module)
&& !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env())
variant_inhabited.apply(self.tcx, cx.typing_env, cx.module)
&& !variant_inhabited.apply_ignore_module(self.tcx, cx.typing_env)
} else {
false
};
@ -789,7 +780,7 @@ fn check_borrow_conflicts_in_at_patterns<'tcx>(cx: &MatchVisitor<'_, 'tcx>, pat:
return;
};
let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env());
let is_binding_by_move = |ty: Ty<'tcx>| !ty.is_copy_modulo_regions(cx.tcx, cx.typing_env);
let sess = cx.tcx.sess;
@ -1054,7 +1045,7 @@ fn find_fallback_pattern_typo<'tcx>(
let mut inaccessible = vec![];
let mut imported = vec![];
let mut imported_spans = vec![];
let infcx = cx.tcx.infer_ctxt().build(ty::TypingMode::non_body_analysis());
let (infcx, param_env) = cx.tcx.infer_ctxt().build_with_typing_env(cx.typing_env);
let parent = cx.tcx.hir().get_parent_item(hir_id);
for item in cx.tcx.hir_crate_items(()).free_items() {
@ -1067,7 +1058,7 @@ fn find_fallback_pattern_typo<'tcx>(
};
for res in &path.res {
if let Res::Def(DefKind::Const, id) = res
&& infcx.can_eq(cx.param_env, ty, cx.tcx.type_of(id).instantiate_identity())
&& infcx.can_eq(param_env, ty, cx.tcx.type_of(id).instantiate_identity())
{
if cx.tcx.visibility(id).is_accessible_from(parent, cx.tcx) {
// The original const is accessible, suggest using it directly.
@ -1088,11 +1079,7 @@ fn find_fallback_pattern_typo<'tcx>(
}
}
if let DefKind::Const = cx.tcx.def_kind(item.owner_id)
&& infcx.can_eq(
cx.param_env,
ty,
cx.tcx.type_of(item.owner_id).instantiate_identity(),
)
&& infcx.can_eq(param_env, ty, cx.tcx.type_of(item.owner_id).instantiate_identity())
{
// Look for local consts.
let item_name = cx.tcx.item_name(item.owner_id.into());
@ -1311,7 +1298,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
}
if let ty::Ref(_, sub_ty, _) = scrut_ty.kind() {
if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env()) {
if !sub_ty.is_inhabited_from(cx.tcx, cx.module, cx.typing_env) {
err.note("references are always considered inhabited");
}
}

View File

@ -9,7 +9,6 @@ use rustc_index::{Idx, IndexVec};
use rustc_middle::middle::stability::EvalResult;
use rustc_middle::mir::{self, Const};
use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
use rustc_middle::traits::Reveal;
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::{
self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef,
@ -86,7 +85,7 @@ pub struct RustcPatCtxt<'p, 'tcx: 'p> {
/// not. E.g., `struct Foo { _private: ! }` cannot be seen to be empty
/// outside its module and should not be matchable with an empty match statement.
pub module: DefId,
pub param_env: ty::ParamEnv<'tcx>,
pub typing_env: ty::TypingEnv<'tcx>,
/// To allocate the result of `self.ctor_sub_tys()`
pub dropless_arena: &'p DroplessArena,
/// Lint level at the match.
@ -109,17 +108,6 @@ impl<'p, 'tcx: 'p> fmt::Debug for RustcPatCtxt<'p, 'tcx> {
}
impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
pub fn typing_mode(&self) -> ty::TypingMode<'tcx> {
debug_assert_eq!(self.param_env.reveal(), Reveal::UserFacing);
// FIXME(#132279): This is inside of a body. If we need to use the `param_env`
// and `typing_mode` we should reveal opaques defined by that body.
ty::TypingMode::non_body_analysis()
}
pub fn typing_env(&self) -> ty::TypingEnv<'tcx> {
ty::TypingEnv { typing_mode: self.typing_mode(), param_env: self.param_env }
}
/// Type inference occasionally gives us opaque types in places where corresponding patterns
/// have more specific types. To avoid inconsistencies as well as detect opaque uninhabited
/// types, we use the corresponding concrete type if possible.
@ -151,7 +139,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
!ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
self.tcx,
self.typing_env(),
self.typing_env,
self.module,
&|key| self.reveal_opaque_key(key),
)
@ -191,7 +179,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
variant.fields.iter().map(move |field| {
let ty = field.ty(self.tcx, args);
// `field.ty()` doesn't normalize after instantiating.
let ty = self.tcx.normalize_erasing_regions(self.typing_env(), ty);
let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty);
let ty = self.reveal_opaque_ty(ty);
(field, ty)
})
@ -381,7 +369,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
let is_inhabited = v
.inhabited_predicate(cx.tcx, *def)
.instantiate(cx.tcx, args)
.apply_revealing_opaque(cx.tcx, cx.typing_env(), cx.module, &|key| {
.apply_revealing_opaque(cx.tcx, cx.typing_env, cx.module, &|key| {
cx.reveal_opaque_key(key)
});
// Variants that depend on a disabled unstable feature.
@ -442,7 +430,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
match bdy {
PatRangeBoundary::NegInfinity => MaybeInfiniteInt::NegInfinity,
PatRangeBoundary::Finite(value) => {
let bits = value.eval_bits(self.tcx, self.typing_env());
let bits = value.eval_bits(self.tcx, self.typing_env);
match *ty.kind() {
ty::Int(ity) => {
let size = Integer::from_int_ty(&self.tcx, ity).size().bits();
@ -551,7 +539,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
PatKind::Constant { value } => {
match ty.kind() {
ty::Bool => {
ctor = match value.try_eval_bool(cx.tcx, cx.typing_env()) {
ctor = match value.try_eval_bool(cx.tcx, cx.typing_env) {
Some(b) => Bool(b),
None => Opaque(OpaqueId::new()),
};
@ -559,7 +547,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
arity = 0;
}
ty::Char | ty::Int(_) | ty::Uint(_) => {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
Some(bits) => {
let x = match *ty.kind() {
ty::Int(ity) => {
@ -576,7 +564,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
arity = 0;
}
ty::Float(ty::FloatTy::F16) => {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
Some(bits) => {
use rustc_apfloat::Float;
let value = rustc_apfloat::ieee::Half::from_bits(bits);
@ -588,7 +576,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
arity = 0;
}
ty::Float(ty::FloatTy::F32) => {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
Some(bits) => {
use rustc_apfloat::Float;
let value = rustc_apfloat::ieee::Single::from_bits(bits);
@ -600,7 +588,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
arity = 0;
}
ty::Float(ty::FloatTy::F64) => {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
Some(bits) => {
use rustc_apfloat::Float;
let value = rustc_apfloat::ieee::Double::from_bits(bits);
@ -612,7 +600,7 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
arity = 0;
}
ty::Float(ty::FloatTy::F128) => {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env()) {
ctor = match value.try_eval_bits(cx.tcx, cx.typing_env) {
Some(bits) => {
use rustc_apfloat::Float;
let value = rustc_apfloat::ieee::Quad::from_bits(bits);
@ -661,8 +649,8 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
}
ty::Float(fty) => {
use rustc_apfloat::Float;
let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env()));
let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env()));
let lo = lo.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env));
let hi = hi.as_finite().map(|c| c.eval_bits(cx.tcx, cx.typing_env));
match fty {
ty::FloatTy::F16 => {
use rustc_apfloat::ieee::Half;