From 4549ef574956f4e5cd6e7aeb54c81a8b4947555d Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sun, 12 Apr 2020 15:34:42 +0200 Subject: [PATCH] emit err when using trait objects in pat --- .../hair/pattern/const_to_pat.rs | 30 +++++++++---------- .../issues/issue-63322-forbid-dyn.stderr | 2 +- src/test/ui/match/issue-70972-dyn-trait.rs | 10 +++++++ .../ui/match/issue-70972-dyn-trait.stderr | 8 +++++ 4 files changed, 33 insertions(+), 17 deletions(-) create mode 100644 src/test/ui/match/issue-70972-dyn-trait.rs create mode 100644 src/test/ui/match/issue-70972-dyn-trait.stderr diff --git a/src/librustc_mir_build/hair/pattern/const_to_pat.rs b/src/librustc_mir_build/hair/pattern/const_to_pat.rs index 6ca7cd47c9c0c..e16e2e2926a20 100644 --- a/src/librustc_mir_build/hair/pattern/const_to_pat.rs +++ b/src/librustc_mir_build/hair/pattern/const_to_pat.rs @@ -101,23 +101,21 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { cv.ty, structural ); if let Some(non_sm_ty) = structural { - let adt_def = match non_sm_ty { - traits::NonStructuralMatchTy::Adt(adt_def) => adt_def, - traits::NonStructuralMatchTy::Param => { - bug!("use of constant whose type is a parameter inside a pattern") + let msg = match non_sm_ty { + traits::NonStructuralMatchTy::Adt(adt_def) => { + let path = self.tcx().def_path_str(adt_def.did); + format!( + "to use a constant of type `{}` in a pattern, \ + `{}` must be annotated with `#[derive(PartialEq, Eq)]`", + path, path, + ) } traits::NonStructuralMatchTy::Dynamic => { - bug!("use of a trait object inside a pattern") + format!("trait objects cannot be used in patterns") + } + traits::NonStructuralMatchTy::Param => { + bug!("use of constant whose type is a parameter inside a pattern") } - }; - let path = self.tcx().def_path_str(adt_def.did); - - let make_msg = || -> String { - format!( - "to use a constant of type `{}` in a pattern, \ - `{}` must be annotated with `#[derive(PartialEq, Eq)]`", - path, path, - ) }; // double-check there even *is* a semantic `PartialEq` to dispatch to. @@ -148,13 +146,13 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { if !ty_is_partial_eq { // span_fatal avoids ICE from resolution of non-existent method (rare case). - self.tcx().sess.span_fatal(self.span, &make_msg()); + self.tcx().sess.span_fatal(self.span, &msg); } else { self.tcx().struct_span_lint_hir( lint::builtin::INDIRECT_STRUCTURAL_MATCH, self.id, self.span, - |lint| lint.build(&make_msg()).emit(), + |lint| lint.build(&msg).emit(), ); } } diff --git a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr index 4b0bf905a88d8..c459b6c435840 100644 --- a/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr +++ b/src/test/ui/const-generics/issues/issue-63322-forbid-dyn.stderr @@ -12,6 +12,6 @@ error[E0741]: the types of const generic parameters must derive `PartialEq` and LL | fn test() { | ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq` -error: aborting due to previous error +error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0741`. diff --git a/src/test/ui/match/issue-70972-dyn-trait.rs b/src/test/ui/match/issue-70972-dyn-trait.rs new file mode 100644 index 0000000000000..a9b2699cafdc4 --- /dev/null +++ b/src/test/ui/match/issue-70972-dyn-trait.rs @@ -0,0 +1,10 @@ +const F: &'static dyn Send = &7u32; + +fn main() { + let a: &dyn Send = &7u32; + match a { + F => panic!(), + //~^ ERROR trait objects cannot be used in patterns + _ => {} + } +} diff --git a/src/test/ui/match/issue-70972-dyn-trait.stderr b/src/test/ui/match/issue-70972-dyn-trait.stderr new file mode 100644 index 0000000000000..a4e827357de6b --- /dev/null +++ b/src/test/ui/match/issue-70972-dyn-trait.stderr @@ -0,0 +1,8 @@ +error: trait objects cannot be used in patterns + --> $DIR/issue-70972-dyn-trait.rs:6:9 + | +LL | F => panic!(), + | ^ + +error: aborting due to previous error +