Skip to content

Commit 07a5272

Browse files
committed
pattern lowering, yeet TypingEnv::from_param_env
1 parent decf37b commit 07a5272

File tree

3 files changed

+38
-63
lines changed

3 files changed

+38
-63
lines changed

compiler/rustc_mir_build/src/thir/cx/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl<'tcx> Cx<'tcx> {
123123

124124
#[instrument(level = "debug", skip(self))]
125125
fn pattern_from_hir(&mut self, p: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
126-
pat_from_hir(self.tcx, self.param_env, self.typeck_results(), p)
126+
pat_from_hir(self.tcx, self.typing_env(), self.typeck_results(), p)
127127
}
128128

129129
fn closure_env_param(&self, owner_def: LocalDefId, expr_id: HirId) -> Option<Param<'tcx>> {

compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs

Lines changed: 33 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@ use rustc_abi::{FieldIdx, VariantIdx};
22
use rustc_apfloat::Float;
33
use rustc_hir as hir;
44
use rustc_index::Idx;
5-
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
5+
use rustc_infer::infer::TyCtxtInferExt;
66
use rustc_infer::traits::Obligation;
77
use rustc_middle::mir::interpret::ErrorHandled;
88
use rustc_middle::thir::{FieldPat, Pat, PatKind};
9-
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, ValTree};
9+
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree};
1010
use rustc_middle::{mir, span_bug};
1111
use rustc_span::Span;
1212
use rustc_trait_selection::traits::ObligationCause;
@@ -35,10 +35,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
3535
id: hir::HirId,
3636
span: Span,
3737
) -> Box<Pat<'tcx>> {
38-
// FIXME(#132279): We likely want to be able to reveal the hidden types
39-
// of opaques defined in this function here.
40-
let infcx = self.tcx.infer_ctxt().build(TypingMode::non_body_analysis());
41-
let mut convert = ConstToPat::new(self, id, span, infcx);
38+
let mut convert = ConstToPat::new(self, id, span);
4239

4340
match c.kind() {
4441
ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
@@ -49,44 +46,29 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
4946
}
5047

5148
struct ConstToPat<'tcx> {
49+
tcx: TyCtxt<'tcx>,
50+
typing_env: ty::TypingEnv<'tcx>,
5251
span: Span,
5352

54-
// inference context used for checking `T: Structural` bounds.
55-
infcx: InferCtxt<'tcx>,
56-
param_env: ty::ParamEnv<'tcx>,
57-
5853
treat_byte_string_as_slice: bool,
5954
}
6055

6156
impl<'tcx> ConstToPat<'tcx> {
62-
fn new(
63-
pat_ctxt: &PatCtxt<'_, 'tcx>,
64-
id: hir::HirId,
65-
span: Span,
66-
infcx: InferCtxt<'tcx>,
67-
) -> Self {
57+
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span) -> Self {
6858
trace!(?pat_ctxt.typeck_results.hir_owner);
6959
ConstToPat {
60+
tcx: pat_ctxt.tcx,
61+
typing_env: pat_ctxt.typing_env,
7062
span,
71-
infcx,
72-
param_env: pat_ctxt.param_env,
7363
treat_byte_string_as_slice: pat_ctxt
7464
.typeck_results
7565
.treat_byte_string_as_slice
7666
.contains(&id.local_id),
7767
}
7868
}
7969

80-
fn tcx(&self) -> TyCtxt<'tcx> {
81-
self.infcx.tcx
82-
}
83-
84-
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
85-
self.infcx.typing_env(self.param_env)
86-
}
87-
8870
fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {
89-
ty.is_structural_eq_shallow(self.infcx.tcx)
71+
ty.is_structural_eq_shallow(self.tcx)
9072
}
9173

9274
fn unevaluated_to_pat(
@@ -105,22 +87,21 @@ impl<'tcx> ConstToPat<'tcx> {
10587
// FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
10688
// instead of having this logic here
10789
let typing_env =
108-
self.tcx().erase_regions(self.typing_env()).with_reveal_all_normalized(self.tcx());
109-
let uv = self.tcx().erase_regions(uv);
90+
self.tcx.erase_regions(self.typing_env).with_reveal_all_normalized(self.tcx);
91+
let uv = self.tcx.erase_regions(uv);
11092

11193
// try to resolve e.g. associated constants to their definition on an impl, and then
11294
// evaluate the const.
113-
let valtree = match self.infcx.tcx.const_eval_resolve_for_typeck(typing_env, uv, self.span)
114-
{
95+
let valtree = match self.tcx.const_eval_resolve_for_typeck(typing_env, uv, self.span) {
11596
Ok(Ok(c)) => c,
11697
Err(ErrorHandled::Reported(_, _)) => {
11798
// Let's tell the use where this failing const occurs.
118-
let e = self.tcx().dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
99+
let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
119100
return pat_from_kind(PatKind::Error(e));
120101
}
121102
Err(ErrorHandled::TooGeneric(_)) => {
122103
let e = self
123-
.tcx()
104+
.tcx
124105
.dcx()
125106
.emit_err(ConstPatternDependsOnGenericParameter { span: self.span });
126107
return pat_from_kind(PatKind::Error(e));
@@ -130,13 +111,13 @@ impl<'tcx> ConstToPat<'tcx> {
130111
let e = match bad_ty.kind() {
131112
ty::Adt(def, ..) => {
132113
assert!(def.is_union());
133-
self.tcx().dcx().emit_err(UnionPattern { span: self.span })
114+
self.tcx.dcx().emit_err(UnionPattern { span: self.span })
134115
}
135116
ty::FnPtr(..) | ty::RawPtr(..) => {
136-
self.tcx().dcx().emit_err(PointerPattern { span: self.span })
117+
self.tcx.dcx().emit_err(PointerPattern { span: self.span })
137118
}
138119
_ => self
139-
.tcx()
120+
.tcx
140121
.dcx()
141122
.emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }),
142123
};
@@ -151,7 +132,7 @@ impl<'tcx> ConstToPat<'tcx> {
151132
// Always check for `PartialEq` if we had no other errors yet.
152133
if !self.type_has_partial_eq_impl(ty) {
153134
let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty };
154-
let e = self.tcx().dcx().emit_err(err);
135+
let e = self.tcx.dcx().emit_err(err);
155136
return pat_from_kind(PatKind::Error(e));
156137
}
157138
}
@@ -161,18 +142,19 @@ impl<'tcx> ConstToPat<'tcx> {
161142

162143
#[instrument(level = "trace", skip(self), ret)]
163144
fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
164-
let tcx = self.tcx();
145+
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
165146
// double-check there even *is* a semantic `PartialEq` to dispatch to.
166147
//
167148
// (If there isn't, then we can safely issue a hard
168149
// error, because that's never worked, due to compiler
169150
// using `PartialEq::eq` in this scenario in the past.)
170-
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
151+
let partial_eq_trait_id =
152+
self.tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
171153
let partial_eq_obligation = Obligation::new(
172-
tcx,
154+
self.tcx,
173155
ObligationCause::dummy(),
174-
self.param_env,
175-
ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
156+
param_env,
157+
ty::TraitRef::new(self.tcx, partial_eq_trait_id, [ty, ty]),
176158
);
177159

178160
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
@@ -181,7 +163,7 @@ impl<'tcx> ConstToPat<'tcx> {
181163
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
182164
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
183165
// can ensure that the type really implements `PartialEq`.
184-
self.infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
166+
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
185167
}
186168

187169
fn field_pats(
@@ -192,7 +174,7 @@ impl<'tcx> ConstToPat<'tcx> {
192174
.map(|(idx, (val, ty))| {
193175
let field = FieldIdx::new(idx);
194176
// Patterns can only use monomorphic types.
195-
let ty = self.tcx().normalize_erasing_regions(self.typing_env(), ty);
177+
let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty);
196178
FieldPat { field, pattern: self.valtree_to_pat(val, ty) }
197179
})
198180
.collect()
@@ -202,12 +184,12 @@ impl<'tcx> ConstToPat<'tcx> {
202184
#[instrument(skip(self), level = "debug")]
203185
fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
204186
let span = self.span;
205-
let tcx = self.tcx();
187+
let tcx = self.tcx;
206188
let kind = match ty.kind() {
207189
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
208190
// Extremely important check for all ADTs! Make sure they opted-in to be used in
209191
// patterns.
210-
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
192+
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
211193
let err = TypeNotStructural { span, non_sm_ty: ty };
212194
let e = tcx.dcx().emit_err(err);
213195
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
@@ -225,22 +207,17 @@ impl<'tcx> ConstToPat<'tcx> {
225207
adt_def.variants()[variant_index]
226208
.fields
227209
.iter()
228-
.map(|field| field.ty(self.tcx(), args)),
210+
.map(|field| field.ty(self.tcx, args)),
229211
),
230212
),
231213
}
232214
}
233215
ty::Adt(def, args) => {
234216
assert!(!def.is_union()); // Valtree construction would never succeed for unions.
235217
PatKind::Leaf {
236-
subpatterns: self.field_pats(
237-
cv.unwrap_branch().iter().copied().zip(
238-
def.non_enum_variant()
239-
.fields
240-
.iter()
241-
.map(|field| field.ty(self.tcx(), args)),
242-
),
243-
),
218+
subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
219+
def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx, args)),
220+
)),
244221
}
245222
}
246223
ty::Tuple(fields) => PatKind::Leaf {
@@ -274,9 +251,7 @@ impl<'tcx> ConstToPat<'tcx> {
274251
// convert the dereferenced constant to a pattern that is the sub-pattern of the
275252
// deref pattern.
276253
_ => {
277-
if !pointee_ty.is_sized(tcx, self.infcx.typing_env(self.param_env))
278-
&& !pointee_ty.is_slice()
279-
{
254+
if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() {
280255
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
281256
let e = tcx.dcx().emit_err(err);
282257
// We errored. Signal that in the pattern, so that follow up errors can be silenced.

compiler/rustc_mir_build/src/thir/pattern/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::thir::util::UserAnnotatedTyHelpers;
3030

3131
struct PatCtxt<'a, 'tcx> {
3232
tcx: TyCtxt<'tcx>,
33-
param_env: ty::ParamEnv<'tcx>,
33+
typing_env: ty::TypingEnv<'tcx>,
3434
typeck_results: &'a ty::TypeckResults<'tcx>,
3535

3636
/// Used by the Rust 2024 migration lint.
@@ -39,13 +39,13 @@ struct PatCtxt<'a, 'tcx> {
3939

4040
pub(super) fn pat_from_hir<'a, 'tcx>(
4141
tcx: TyCtxt<'tcx>,
42-
param_env: ty::ParamEnv<'tcx>,
42+
typing_env: ty::TypingEnv<'tcx>,
4343
typeck_results: &'a ty::TypeckResults<'tcx>,
4444
pat: &'tcx hir::Pat<'tcx>,
4545
) -> Box<Pat<'tcx>> {
4646
let mut pcx = PatCtxt {
4747
tcx,
48-
param_env,
48+
typing_env,
4949
typeck_results,
5050
rust_2024_migration_suggestion: typeck_results
5151
.rust_2024_migration_desugared_pats()
@@ -242,7 +242,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
242242
let lo = lo.unwrap_or(PatRangeBoundary::NegInfinity);
243243
let hi = hi.unwrap_or(PatRangeBoundary::PosInfinity);
244244

245-
let cmp = lo.compare_with(hi, ty, self.tcx, ty::TypingEnv::from_param_env(self.param_env));
245+
let cmp = lo.compare_with(hi, ty, self.tcx, self.typing_env);
246246
let mut kind = PatKind::Range(Box::new(PatRange { lo, hi, end, ty }));
247247
match (end, cmp) {
248248
// `x..y` where `x < y`.

0 commit comments

Comments
 (0)