Cleanup PatCtxt.
This commit is contained in:
parent
05082f57af
commit
4240a0bed0
2 changed files with 23 additions and 73 deletions
|
@ -59,8 +59,6 @@ struct ConstToPat<'tcx> {
|
||||||
// inference context used for checking `T: Structural` bounds.
|
// inference context used for checking `T: Structural` bounds.
|
||||||
infcx: InferCtxt<'tcx>,
|
infcx: InferCtxt<'tcx>,
|
||||||
|
|
||||||
include_lint_checks: bool,
|
|
||||||
|
|
||||||
treat_byte_string_as_slice: bool,
|
treat_byte_string_as_slice: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +91,6 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
span,
|
span,
|
||||||
infcx,
|
infcx,
|
||||||
param_env: pat_ctxt.param_env,
|
param_env: pat_ctxt.param_env,
|
||||||
include_lint_checks: pat_ctxt.include_lint_checks,
|
|
||||||
saw_const_match_error: Cell::new(false),
|
saw_const_match_error: Cell::new(false),
|
||||||
saw_const_match_lint: Cell::new(false),
|
saw_const_match_lint: Cell::new(false),
|
||||||
behind_reference: Cell::new(false),
|
behind_reference: Cell::new(false),
|
||||||
|
@ -134,7 +131,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
if self.include_lint_checks && !self.saw_const_match_error.get() {
|
if !self.saw_const_match_error.get() {
|
||||||
// If we were able to successfully convert the const to some pat,
|
// If we were able to successfully convert the const to some pat,
|
||||||
// double-check that all types in the const implement `Structural`.
|
// double-check that all types in the const implement `Structural`.
|
||||||
|
|
||||||
|
@ -239,21 +236,19 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
|
|
||||||
let kind = match cv.ty().kind() {
|
let kind = match cv.ty().kind() {
|
||||||
ty::Float(_) => {
|
ty::Float(_) => {
|
||||||
if self.include_lint_checks {
|
|
||||||
tcx.emit_spanned_lint(
|
tcx.emit_spanned_lint(
|
||||||
lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
|
lint::builtin::ILLEGAL_FLOATING_POINT_LITERAL_PATTERN,
|
||||||
id,
|
id,
|
||||||
span,
|
span,
|
||||||
FloatPattern,
|
FloatPattern,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
PatKind::Constant { value: cv }
|
PatKind::Constant { value: cv }
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, _) if adt_def.is_union() => {
|
ty::Adt(adt_def, _) if adt_def.is_union() => {
|
||||||
// Matching on union fields is unsafe, we can't hide it in constants
|
// Matching on union fields is unsafe, we can't hide it in constants
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = UnionPattern { span };
|
let err = UnionPattern { span };
|
||||||
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
|
tcx.sess.emit_err(err);
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
ty::Adt(..)
|
ty::Adt(..)
|
||||||
|
@ -267,7 +262,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
{
|
{
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = TypeNotStructural { span, non_sm_ty };
|
let err = TypeNotStructural { span, non_sm_ty };
|
||||||
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
|
tcx.sess.emit_err(err);
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
// If the type is not structurally comparable, just emit the constant directly,
|
// If the type is not structurally comparable, just emit the constant directly,
|
||||||
|
@ -280,8 +275,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// Backwards compatibility hack because we can't cause hard errors on these
|
// Backwards compatibility hack because we can't cause hard errors on these
|
||||||
// types, so we compare them via `PartialEq::eq` at runtime.
|
// types, so we compare them via `PartialEq::eq` at runtime.
|
||||||
ty::Adt(..) if !self.type_marked_structural(cv.ty()) && self.behind_reference.get() => {
|
ty::Adt(..) if !self.type_marked_structural(cv.ty()) && self.behind_reference.get() => {
|
||||||
if self.include_lint_checks
|
if !self.saw_const_match_error.get()
|
||||||
&& !self.saw_const_match_error.get()
|
|
||||||
&& !self.saw_const_match_lint.get()
|
&& !self.saw_const_match_lint.get()
|
||||||
{
|
{
|
||||||
self.saw_const_match_lint.set(true);
|
self.saw_const_match_lint.set(true);
|
||||||
|
@ -305,7 +299,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
);
|
);
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = TypeNotStructural { span, non_sm_ty: cv.ty() };
|
let err = TypeNotStructural { span, non_sm_ty: cv.ty() };
|
||||||
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
|
tcx.sess.emit_err(err);
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
ty::Adt(adt_def, substs) if adt_def.is_enum() => {
|
ty::Adt(adt_def, substs) if adt_def.is_enum() => {
|
||||||
|
@ -339,7 +333,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
ty::Dynamic(..) => {
|
ty::Dynamic(..) => {
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = InvalidPattern { span, non_sm_ty: cv.ty() };
|
let err = InvalidPattern { span, non_sm_ty: cv.ty() };
|
||||||
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
|
tcx.sess.emit_err(err);
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
// `&str` is represented as `ConstValue::Slice`, let's keep using this
|
// `&str` is represented as `ConstValue::Slice`, let's keep using this
|
||||||
|
@ -406,8 +400,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// to figure out how to get a reference again.
|
// to figure out how to get a reference again.
|
||||||
ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
|
ty::Adt(_, _) if !self.type_marked_structural(*pointee_ty) => {
|
||||||
if self.behind_reference.get() {
|
if self.behind_reference.get() {
|
||||||
if self.include_lint_checks
|
if !self.saw_const_match_error.get()
|
||||||
&& !self.saw_const_match_error.get()
|
|
||||||
&& !self.saw_const_match_lint.get()
|
&& !self.saw_const_match_lint.get()
|
||||||
{
|
{
|
||||||
self.saw_const_match_lint.set(true);
|
self.saw_const_match_lint.set(true);
|
||||||
|
@ -423,7 +416,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
if !self.saw_const_match_error.get() {
|
if !self.saw_const_match_error.get() {
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
|
let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
|
||||||
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
|
tcx.sess.emit_err(err);
|
||||||
}
|
}
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
|
@ -437,7 +430,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// (except slices, which are handled in a separate arm above).
|
// (except slices, which are handled in a separate arm above).
|
||||||
|
|
||||||
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
|
let err = UnsizedPattern { span, non_sm_ty: *pointee_ty };
|
||||||
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
|
tcx.sess.emit_err(err);
|
||||||
|
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
} else {
|
} else {
|
||||||
|
@ -465,8 +458,7 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
// compilation choices change the runtime behaviour of the match.
|
// compilation choices change the runtime behaviour of the match.
|
||||||
// See https://github.com/rust-lang/rust/issues/70861 for examples.
|
// See https://github.com/rust-lang/rust/issues/70861 for examples.
|
||||||
ty::FnPtr(..) | ty::RawPtr(..) => {
|
ty::FnPtr(..) | ty::RawPtr(..) => {
|
||||||
if self.include_lint_checks
|
if !self.saw_const_match_error.get()
|
||||||
&& !self.saw_const_match_error.get()
|
|
||||||
&& !self.saw_const_match_lint.get()
|
&& !self.saw_const_match_lint.get()
|
||||||
{
|
{
|
||||||
self.saw_const_match_lint.set(true);
|
self.saw_const_match_lint.set(true);
|
||||||
|
@ -482,13 +474,12 @@ impl<'tcx> ConstToPat<'tcx> {
|
||||||
_ => {
|
_ => {
|
||||||
self.saw_const_match_error.set(true);
|
self.saw_const_match_error.set(true);
|
||||||
let err = InvalidPattern { span, non_sm_ty: cv.ty() };
|
let err = InvalidPattern { span, non_sm_ty: cv.ty() };
|
||||||
tcx.sess.create_err(err).emit_unless(!self.include_lint_checks);
|
tcx.sess.emit_err(err);
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.include_lint_checks
|
if !self.saw_const_match_error.get()
|
||||||
&& !self.saw_const_match_error.get()
|
|
||||||
&& !self.saw_const_match_lint.get()
|
&& !self.saw_const_match_lint.get()
|
||||||
&& mir_structural_match_violation
|
&& mir_structural_match_violation
|
||||||
// FIXME(#73448): Find a way to bring const qualification into parity with
|
// FIXME(#73448): Find a way to bring const qualification into parity with
|
||||||
|
|
|
@ -31,20 +31,10 @@ use rustc_target::abi::FieldIdx;
|
||||||
|
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
enum PatternError {
|
|
||||||
AssocConstInPattern(Span),
|
|
||||||
ConstParamInPattern(Span),
|
|
||||||
StaticInPattern(Span),
|
|
||||||
NonConstPath(Span),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PatCtxt<'a, 'tcx> {
|
struct PatCtxt<'a, 'tcx> {
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||||
errors: Vec<PatternError>,
|
|
||||||
include_lint_checks: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn pat_from_hir<'a, 'tcx>(
|
pub(super) fn pat_from_hir<'a, 'tcx>(
|
||||||
|
@ -53,47 +43,13 @@ pub(super) fn pat_from_hir<'a, 'tcx>(
|
||||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||||
pat: &'tcx hir::Pat<'tcx>,
|
pat: &'tcx hir::Pat<'tcx>,
|
||||||
) -> Box<Pat<'tcx>> {
|
) -> Box<Pat<'tcx>> {
|
||||||
let mut pcx = PatCtxt::new(tcx, param_env, typeck_results);
|
let mut pcx = PatCtxt { tcx, param_env, typeck_results };
|
||||||
pcx.include_lint_checks();
|
|
||||||
let result = pcx.lower_pattern(pat);
|
let result = pcx.lower_pattern(pat);
|
||||||
pcx.report_inlining_errors();
|
|
||||||
debug!("pat_from_hir({:?}) = {:?}", pat, result);
|
debug!("pat_from_hir({:?}) = {:?}", pat, result);
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
fn new(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
|
||||||
typeck_results: &'a ty::TypeckResults<'tcx>,
|
|
||||||
) -> Self {
|
|
||||||
PatCtxt { tcx, param_env, typeck_results, errors: vec![], include_lint_checks: false }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn include_lint_checks(&mut self) -> &mut Self {
|
|
||||||
self.include_lint_checks = true;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn report_inlining_errors(&self) {
|
|
||||||
for error in &self.errors {
|
|
||||||
match *error {
|
|
||||||
PatternError::StaticInPattern(span) => {
|
|
||||||
self.tcx.sess.emit_err(StaticInPattern { span });
|
|
||||||
}
|
|
||||||
PatternError::AssocConstInPattern(span) => {
|
|
||||||
self.tcx.sess.emit_err(AssocConstInPattern { span });
|
|
||||||
}
|
|
||||||
PatternError::ConstParamInPattern(span) => {
|
|
||||||
self.tcx.sess.emit_err(ConstParamInPattern { span });
|
|
||||||
}
|
|
||||||
PatternError::NonConstPath(span) => {
|
|
||||||
self.tcx.sess.emit_err(NonConstPath { span });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
fn lower_pattern(&mut self, pat: &'tcx hir::Pat<'tcx>) -> Box<Pat<'tcx>> {
|
||||||
// When implicit dereferences have been inserted in this pattern, the unadjusted lowered
|
// When implicit dereferences have been inserted in this pattern, the unadjusted lowered
|
||||||
// pattern has the type that results *after* dereferencing. For example, in this code:
|
// pattern has the type that results *after* dereferencing. For example, in this code:
|
||||||
|
@ -490,12 +446,15 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
| Res::SelfTyAlias { .. }
|
| Res::SelfTyAlias { .. }
|
||||||
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
|
| Res::SelfCtor(..) => PatKind::Leaf { subpatterns },
|
||||||
_ => {
|
_ => {
|
||||||
let pattern_error = match res {
|
match res {
|
||||||
Res::Def(DefKind::ConstParam, _) => PatternError::ConstParamInPattern(span),
|
Res::Def(DefKind::ConstParam, _) => {
|
||||||
Res::Def(DefKind::Static(_), _) => PatternError::StaticInPattern(span),
|
self.tcx.sess.emit_err(ConstParamInPattern { span })
|
||||||
_ => PatternError::NonConstPath(span),
|
}
|
||||||
|
Res::Def(DefKind::Static(_), _) => {
|
||||||
|
self.tcx.sess.emit_err(StaticInPattern { span })
|
||||||
|
}
|
||||||
|
_ => self.tcx.sess.emit_err(NonConstPath { span }),
|
||||||
};
|
};
|
||||||
self.errors.push(pattern_error);
|
|
||||||
PatKind::Wild
|
PatKind::Wild
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -548,7 +507,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
// It should be assoc consts if there's no error but we cannot resolve it.
|
// It should be assoc consts if there's no error but we cannot resolve it.
|
||||||
debug_assert!(is_associated_const);
|
debug_assert!(is_associated_const);
|
||||||
|
|
||||||
self.errors.push(PatternError::AssocConstInPattern(span));
|
self.tcx.sess.emit_err(AssocConstInPattern { span });
|
||||||
|
|
||||||
return pat_from_kind(PatKind::Wild);
|
return pat_from_kind(PatKind::Wild);
|
||||||
}
|
}
|
||||||
|
@ -626,7 +585,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
|
||||||
match value {
|
match value {
|
||||||
mir::ConstantKind::Ty(c) => match c.kind() {
|
mir::ConstantKind::Ty(c) => match c.kind() {
|
||||||
ConstKind::Param(_) => {
|
ConstKind::Param(_) => {
|
||||||
self.errors.push(PatternError::ConstParamInPattern(span));
|
self.tcx.sess.emit_err(ConstParamInPattern { span });
|
||||||
return PatKind::Wild;
|
return PatKind::Wild;
|
||||||
}
|
}
|
||||||
ConstKind::Error(_) => {
|
ConstKind::Error(_) => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue