diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-01-20 19:46:06 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-01-20 19:46:27 +0100 |
| commit | 78f0c7fd6433c60d031311dacbf9a117b05e64b3 (patch) | |
| tree | 7912360ea86d93d338819fcb3dddf494f3521b13 | |
| parent | 71450c7aadac3a94889744143127962c4e991f60 (diff) | |
| download | rust-78f0c7fd6433c60d031311dacbf9a117b05e64b3.tar.gz rust-78f0c7fd6433c60d031311dacbf9a117b05e64b3.zip | |
check_match: unify some lowering code and fix some ICEs
8 files changed, 100 insertions, 19 deletions
diff --git a/src/librustc_mir_build/hair/pattern/_match.rs b/src/librustc_mir_build/hair/pattern/_match.rs index 8fcaa1e8082..20183fd55c8 100644 --- a/src/librustc_mir_build/hair/pattern/_match.rs +++ b/src/librustc_mir_build/hair/pattern/_match.rs @@ -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 }) diff --git a/src/librustc_mir_build/hair/pattern/check_match.rs b/src/librustc_mir_build/hair/pattern/check_match.rs index ced0d5ed935..5462d08e3cc 100644 --- a/src/librustc_mir_build/hair/pattern/check_match.rs +++ b/src/librustc_mir_build/hair/pattern/check_match.rs @@ -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) { diff --git a/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs new file mode 100644 index 00000000000..95ead6b5d4a --- /dev/null +++ b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.rs @@ -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() {} diff --git a/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr new file mode 100644 index 00000000000..54ecc24981f --- /dev/null +++ b/src/test/ui/pattern/issue-68393-let-pat-assoc-constant.stderr @@ -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`. diff --git a/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs new file mode 100644 index 00000000000..f10a7f2d8a5 --- /dev/null +++ b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.rs @@ -0,0 +1,5 @@ +fn main() { + let x = 255u8; + let 0u8..=x = 0; + //~^ ERROR runtime values cannot be referenced in patterns +} diff --git a/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr new file mode 100644 index 00000000000..c1508bd71ff --- /dev/null +++ b/src/test/ui/pattern/issue-68394-let-pat-runtime-value.stderr @@ -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`. diff --git a/src/test/ui/pattern/issue-68396-let-float-bug.rs b/src/test/ui/pattern/issue-68396-let-float-bug.rs new file mode 100644 index 00000000000..afc599a4b22 --- /dev/null +++ b/src/test/ui/pattern/issue-68396-let-float-bug.rs @@ -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) +} diff --git a/src/test/ui/pattern/issue-68396-let-float-bug.stderr b/src/test/ui/pattern/issue-68396-let-float-bug.stderr new file mode 100644 index 00000000000..618aa4b5021 --- /dev/null +++ b/src/test/ui/pattern/issue-68396-let-float-bug.stderr @@ -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`. |
