check_match: unify some lowering code and fix some ICEs

This commit is contained in:
Mazdak Farrokhzad 2020-01-20 19:46:06 +01:00
parent 71450c7aad
commit 78f0c7fd64
8 changed files with 100 additions and 19 deletions

View File

@ -582,15 +582,12 @@ crate struct MatchCheckCtxt<'a, 'tcx> {
}
impl<'a, 'tcx> MatchCheckCtxt<'a, 'tcx> {
crate fn create_and_enter<F, R>(
crate fn create_and_enter<R>(
tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>,
module: DefId,
f: F,
) -> R
where
F: for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R,
{
f: impl for<'b> FnOnce(MatchCheckCtxt<'b, 'tcx>) -> R,
) -> R {
let pattern_arena = TypedArena::default();
f(MatchCheckCtxt { tcx, param_env, module, pattern_arena: &pattern_arena })

View File

@ -121,6 +121,24 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
check_for_bindings_named_same_as_variants(self, pat);
}
fn lower_pattern<'p>(
&self,
cx: &mut MatchCheckCtxt<'p, 'tcx>,
pat: &'tcx hir::Pat<'tcx>,
have_errors: &mut bool,
) -> (&'p super::Pat<'tcx>, Ty<'tcx>) {
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
patcx.include_lint_checks();
let pattern = patcx.lower_pattern(pat);
let pattern_ty = pattern.ty;
let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
if !patcx.errors.is_empty() {
*have_errors = true;
patcx.report_inlining_errors(pat.span);
}
(pattern, pattern_ty)
}
fn check_match(
&mut self,
scrut: &hir::Expr<'_>,
@ -139,14 +157,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
let inlined_arms: Vec<_> = arms
.iter()
.map(|arm| {
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
patcx.include_lint_checks();
let pattern = patcx.lower_pattern(&arm.pat);
let pattern: &_ = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
if !patcx.errors.is_empty() {
patcx.report_inlining_errors(arm.pat.span);
have_errors = true;
}
let (pattern, _) = self.lower_pattern(cx, &arm.pat, &mut have_errors);
(pattern, &*arm.pat, arm.guard.is_some())
})
.collect();
@ -171,11 +182,7 @@ impl<'tcx> MatchVisitor<'_, 'tcx> {
fn check_irrefutable(&self, pat: &'tcx Pat<'tcx>, origin: &str, sp: Option<Span>) {
let module = self.tcx.hir().get_module_parent(pat.hir_id);
MatchCheckCtxt::create_and_enter(self.tcx, self.param_env, module, |ref mut cx| {
let mut patcx = PatCtxt::new(self.tcx, self.param_env, self.tables);
patcx.include_lint_checks();
let pattern = patcx.lower_pattern(pat);
let pattern_ty = pattern.ty;
let pattern = cx.pattern_arena.alloc(expand_pattern(cx, pattern));
let (pattern, pattern_ty) = self.lower_pattern(cx, pat, &mut false);
let pats: Matrix<'_, '_> = vec![PatStack::from_pattern(pattern)].into_iter().collect();
let witnesses = match check_not_useful(cx, pattern_ty, &pats, pat.hir_id) {

View File

@ -0,0 +1,26 @@
pub enum EFoo {
A,
}
pub trait Foo {
const X: EFoo;
}
struct Abc;
impl Foo for Abc {
const X: EFoo = EFoo::A;
}
struct Def;
impl Foo for Def {
const X: EFoo = EFoo::A;
}
pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
//~^ ERROR associated consts cannot be referenced in patterns
let A::X = arg;
//~^ ERROR associated consts cannot be referenced in patterns
}
fn main() {}

View File

@ -0,0 +1,15 @@
error[E0158]: associated consts cannot be referenced in patterns
--> $DIR/issue-68393-let-pat-assoc-constant.rs:20:40
|
LL | pub fn test<A: Foo, B: Foo>(arg: EFoo, A::X: EFoo) {
| ^^^^
error[E0158]: associated consts cannot be referenced in patterns
--> $DIR/issue-68393-let-pat-assoc-constant.rs:22:9
|
LL | let A::X = arg;
| ^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0158`.

View File

@ -0,0 +1,5 @@
fn main() {
let x = 255u8;
let 0u8..=x = 0;
//~^ ERROR runtime values cannot be referenced in patterns
}

View File

@ -0,0 +1,9 @@
error[E0080]: runtime values cannot be referenced in patterns
--> $DIR/issue-68394-let-pat-runtime-value.rs:3:15
|
LL | let 0u8..=x = 0;
| ^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`.

View File

@ -0,0 +1,7 @@
fn main() {
let 1234567890123456789012345678901234567890e-340: f64 = 0.0;
//~^ ERROR could not evaluate float literal (see issue #31407)
fn param(1234567890123456789012345678901234567890e-340: f64) {}
//~^ ERROR could not evaluate float literal (see issue #31407)
}

View File

@ -0,0 +1,15 @@
error[E0080]: could not evaluate float literal (see issue #31407)
--> $DIR/issue-68396-let-float-bug.rs:2:9
|
LL | let 1234567890123456789012345678901234567890e-340: f64 = 0.0;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0080]: could not evaluate float literal (see issue #31407)
--> $DIR/issue-68396-let-float-bug.rs:5:14
|
LL | fn param(1234567890123456789012345678901234567890e-340: f64) {}
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0080`.