mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
pattern lowering, yeet TypingEnv::from_param_env
This commit is contained in:
parent
decf37bd16
commit
07a5272476
@ -123,7 +123,7 @@ impl<'tcx> Cx<'tcx> {
|
||||
|
||||
#[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.param_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>> {
|
||||
|
@ -2,11 +2,11 @@ use rustc_abi::{FieldIdx, VariantIdx};
|
||||
use rustc_apfloat::Float;
|
||||
use rustc_hir as hir;
|
||||
use rustc_index::Idx;
|
||||
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_infer::traits::Obligation;
|
||||
use rustc_middle::mir::interpret::ErrorHandled;
|
||||
use rustc_middle::thir::{FieldPat, Pat, PatKind};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, ValTree};
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, ValTree};
|
||||
use rustc_middle::{mir, span_bug};
|
||||
use rustc_span::Span;
|
||||
use rustc_trait_selection::traits::ObligationCause;
|
||||
@ -35,10 +35,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
id: hir::HirId,
|
||||
span: Span,
|
||||
) -> Box<Pat<'tcx>> {
|
||||
// FIXME(#132279): We likely want to be able to reveal the hidden types
|
||||
// of opaques defined in this function here.
|
||||
let infcx = self.tcx.infer_ctxt().build(TypingMode::non_body_analysis());
|
||||
let mut convert = ConstToPat::new(self, id, span, infcx);
|
||||
let mut convert = ConstToPat::new(self, id, span);
|
||||
|
||||
match c.kind() {
|
||||
ty::ConstKind::Unevaluated(uv) => convert.unevaluated_to_pat(uv, ty),
|
||||
@ -49,27 +46,20 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
struct ConstToPat<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
span: Span,
|
||||
|
||||
// inference context used for checking `T: Structural` bounds.
|
||||
infcx: InferCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
|
||||
treat_byte_string_as_slice: bool,
|
||||
}
|
||||
|
||||
impl<'tcx> ConstToPat<'tcx> {
|
||||
fn new(
|
||||
pat_ctxt: &PatCtxt<'_, 'tcx>,
|
||||
id: hir::HirId,
|
||||
span: Span,
|
||||
infcx: InferCtxt<'tcx>,
|
||||
) -> Self {
|
||||
fn new(pat_ctxt: &PatCtxt<'_, 'tcx>, id: hir::HirId, span: Span) -> Self {
|
||||
trace!(?pat_ctxt.typeck_results.hir_owner);
|
||||
ConstToPat {
|
||||
tcx: pat_ctxt.tcx,
|
||||
typing_env: pat_ctxt.typing_env,
|
||||
span,
|
||||
infcx,
|
||||
param_env: pat_ctxt.param_env,
|
||||
treat_byte_string_as_slice: pat_ctxt
|
||||
.typeck_results
|
||||
.treat_byte_string_as_slice
|
||||
@ -77,16 +67,8 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn tcx(&self) -> TyCtxt<'tcx> {
|
||||
self.infcx.tcx
|
||||
}
|
||||
|
||||
fn typing_env(&self) -> ty::TypingEnv<'tcx> {
|
||||
self.infcx.typing_env(self.param_env)
|
||||
}
|
||||
|
||||
fn type_marked_structural(&self, ty: Ty<'tcx>) -> bool {
|
||||
ty.is_structural_eq_shallow(self.infcx.tcx)
|
||||
ty.is_structural_eq_shallow(self.tcx)
|
||||
}
|
||||
|
||||
fn unevaluated_to_pat(
|
||||
@ -105,22 +87,21 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
// FIXME: `const_eval_resolve_for_typeck` should probably just set the env to `Reveal::All`
|
||||
// instead of having this logic here
|
||||
let typing_env =
|
||||
self.tcx().erase_regions(self.typing_env()).with_reveal_all_normalized(self.tcx());
|
||||
let uv = self.tcx().erase_regions(uv);
|
||||
self.tcx.erase_regions(self.typing_env).with_reveal_all_normalized(self.tcx);
|
||||
let uv = self.tcx.erase_regions(uv);
|
||||
|
||||
// try to resolve e.g. associated constants to their definition on an impl, and then
|
||||
// evaluate the const.
|
||||
let valtree = match self.infcx.tcx.const_eval_resolve_for_typeck(typing_env, uv, self.span)
|
||||
{
|
||||
let valtree = match self.tcx.const_eval_resolve_for_typeck(typing_env, uv, self.span) {
|
||||
Ok(Ok(c)) => c,
|
||||
Err(ErrorHandled::Reported(_, _)) => {
|
||||
// Let's tell the use where this failing const occurs.
|
||||
let e = self.tcx().dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
|
||||
let e = self.tcx.dcx().emit_err(CouldNotEvalConstPattern { span: self.span });
|
||||
return pat_from_kind(PatKind::Error(e));
|
||||
}
|
||||
Err(ErrorHandled::TooGeneric(_)) => {
|
||||
let e = self
|
||||
.tcx()
|
||||
.tcx
|
||||
.dcx()
|
||||
.emit_err(ConstPatternDependsOnGenericParameter { span: self.span });
|
||||
return pat_from_kind(PatKind::Error(e));
|
||||
@ -130,13 +111,13 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
let e = match bad_ty.kind() {
|
||||
ty::Adt(def, ..) => {
|
||||
assert!(def.is_union());
|
||||
self.tcx().dcx().emit_err(UnionPattern { span: self.span })
|
||||
self.tcx.dcx().emit_err(UnionPattern { span: self.span })
|
||||
}
|
||||
ty::FnPtr(..) | ty::RawPtr(..) => {
|
||||
self.tcx().dcx().emit_err(PointerPattern { span: self.span })
|
||||
self.tcx.dcx().emit_err(PointerPattern { span: self.span })
|
||||
}
|
||||
_ => self
|
||||
.tcx()
|
||||
.tcx
|
||||
.dcx()
|
||||
.emit_err(InvalidPattern { span: self.span, non_sm_ty: bad_ty }),
|
||||
};
|
||||
@ -151,7 +132,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
// Always check for `PartialEq` if we had no other errors yet.
|
||||
if !self.type_has_partial_eq_impl(ty) {
|
||||
let err = TypeNotPartialEq { span: self.span, non_peq_ty: ty };
|
||||
let e = self.tcx().dcx().emit_err(err);
|
||||
let e = self.tcx.dcx().emit_err(err);
|
||||
return pat_from_kind(PatKind::Error(e));
|
||||
}
|
||||
}
|
||||
@ -161,18 +142,19 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
|
||||
let tcx = self.tcx();
|
||||
let (infcx, param_env) = self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
|
||||
// double-check there even *is* a semantic `PartialEq` to dispatch to.
|
||||
//
|
||||
// (If there isn't, then we can safely issue a hard
|
||||
// error, because that's never worked, due to compiler
|
||||
// using `PartialEq::eq` in this scenario in the past.)
|
||||
let partial_eq_trait_id = tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
||||
let partial_eq_trait_id =
|
||||
self.tcx.require_lang_item(hir::LangItem::PartialEq, Some(self.span));
|
||||
let partial_eq_obligation = Obligation::new(
|
||||
tcx,
|
||||
self.tcx,
|
||||
ObligationCause::dummy(),
|
||||
self.param_env,
|
||||
ty::TraitRef::new(tcx, partial_eq_trait_id, [ty, ty]),
|
||||
param_env,
|
||||
ty::TraitRef::new(self.tcx, partial_eq_trait_id, [ty, ty]),
|
||||
);
|
||||
|
||||
// This *could* accept a type that isn't actually `PartialEq`, because region bounds get
|
||||
@ -181,7 +163,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
// `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
|
||||
// we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
|
||||
// can ensure that the type really implements `PartialEq`.
|
||||
self.infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
|
||||
infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
|
||||
}
|
||||
|
||||
fn field_pats(
|
||||
@ -192,7 +174,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
.map(|(idx, (val, ty))| {
|
||||
let field = FieldIdx::new(idx);
|
||||
// Patterns can only use monomorphic types.
|
||||
let ty = self.tcx().normalize_erasing_regions(self.typing_env(), ty);
|
||||
let ty = self.tcx.normalize_erasing_regions(self.typing_env, ty);
|
||||
FieldPat { field, pattern: self.valtree_to_pat(val, ty) }
|
||||
})
|
||||
.collect()
|
||||
@ -202,12 +184,12 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
#[instrument(skip(self), level = "debug")]
|
||||
fn valtree_to_pat(&self, cv: ValTree<'tcx>, ty: Ty<'tcx>) -> Box<Pat<'tcx>> {
|
||||
let span = self.span;
|
||||
let tcx = self.tcx();
|
||||
let tcx = self.tcx;
|
||||
let kind = match ty.kind() {
|
||||
ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
|
||||
// Extremely important check for all ADTs! Make sure they opted-in to be used in
|
||||
// patterns.
|
||||
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty,);
|
||||
debug!("adt_def {:?} has !type_marked_structural for cv.ty: {:?}", adt_def, ty);
|
||||
let err = TypeNotStructural { span, non_sm_ty: ty };
|
||||
let e = tcx.dcx().emit_err(err);
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
@ -225,7 +207,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
adt_def.variants()[variant_index]
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| field.ty(self.tcx(), args)),
|
||||
.map(|field| field.ty(self.tcx, args)),
|
||||
),
|
||||
),
|
||||
}
|
||||
@ -233,14 +215,9 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
ty::Adt(def, args) => {
|
||||
assert!(!def.is_union()); // Valtree construction would never succeed for unions.
|
||||
PatKind::Leaf {
|
||||
subpatterns: self.field_pats(
|
||||
cv.unwrap_branch().iter().copied().zip(
|
||||
def.non_enum_variant()
|
||||
.fields
|
||||
.iter()
|
||||
.map(|field| field.ty(self.tcx(), args)),
|
||||
),
|
||||
),
|
||||
subpatterns: self.field_pats(cv.unwrap_branch().iter().copied().zip(
|
||||
def.non_enum_variant().fields.iter().map(|field| field.ty(self.tcx, args)),
|
||||
)),
|
||||
}
|
||||
}
|
||||
ty::Tuple(fields) => PatKind::Leaf {
|
||||
@ -274,9 +251,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||
// convert the dereferenced constant to a pattern that is the sub-pattern of the
|
||||
// deref pattern.
|
||||
_ => {
|
||||
if !pointee_ty.is_sized(tcx, self.infcx.typing_env(self.param_env))
|
||||
&& !pointee_ty.is_slice()
|
||||
{
|
||||
if !pointee_ty.is_sized(tcx, self.typing_env) && !pointee_ty.is_slice() {
|
||||
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
|
||||
let e = tcx.dcx().emit_err(err);
|
||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||
|
@ -30,7 +30,7 @@ use crate::thir::util::UserAnnotatedTyHelpers;
|
||||
|
||||
struct PatCtxt<'a, 'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
|
||||
/// Used by the Rust 2024 migration lint.
|
||||
@ -39,13 +39,13 @@ struct PatCtxt<'a, 'tcx> {
|
||||
|
||||
pub(super) fn pat_from_hir<'a, 'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
typing_env: ty::TypingEnv<'tcx>,
|
||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||
pat: &'tcx hir::Pat<'tcx>,
|
||||
) -> Box<Pat<'tcx>> {
|
||||
let mut pcx = PatCtxt {
|
||||
tcx,
|
||||
param_env,
|
||||
typing_env,
|
||||
typeck_results,
|
||||
rust_2024_migration_suggestion: typeck_results
|
||||
.rust_2024_migration_desugared_pats()
|
||||
@ -242,7 +242,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||
let lo = lo.unwrap_or(PatRangeBoundary::NegInfinity);
|
||||
let hi = hi.unwrap_or(PatRangeBoundary::PosInfinity);
|
||||
|
||||
let cmp = lo.compare_with(hi, ty, self.tcx, ty::TypingEnv::from_param_env(self.param_env));
|
||||
let cmp = lo.compare_with(hi, ty, self.tcx, self.typing_env);
|
||||
let mut kind = PatKind::Range(Box::new(PatRange { lo, hi, end, ty }));
|
||||
match (end, cmp) {
|
||||
// `x..y` where `x < y`.
|
||||
|
Loading…
Reference in New Issue
Block a user