mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Rollup merge of #71038 - lcnr:dyn_trait_structural_match, r=pnkfelix
forbid `dyn Trait` in patterns Do not allow `&dyn Trait` as a generic const parameters. This also changes dyn trait in pattern from ICE to error. closes #63322 closes #70972 r? @eddyb
This commit is contained in:
commit
679431f741
@ -111,20 +111,21 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
let make_msg = || -> String {
|
||||
format!(
|
||||
"to use a constant of type `{}` in a pattern, \
|
||||
`{}` must be annotated with `#[derive(PartialEq, Eq)]`",
|
||||
path, path,
|
||||
)
|
||||
}
|
||||
traits::NonStructuralMatchTy::Dynamic => {
|
||||
format!("trait objects cannot be used in patterns")
|
||||
}
|
||||
traits::NonStructuralMatchTy::Param => {
|
||||
bug!("use of constant whose type is a parameter inside a pattern")
|
||||
}
|
||||
};
|
||||
|
||||
// double-check there even *is* a semantic `PartialEq` to dispatch to.
|
||||
@ -155,13 +156,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 if mir_structural_match_violation {
|
||||
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(),
|
||||
);
|
||||
} else {
|
||||
debug!(
|
||||
|
@ -11,6 +11,7 @@ use rustc_span::Span;
|
||||
pub enum NonStructuralMatchTy<'tcx> {
|
||||
Adt(&'tcx AdtDef),
|
||||
Param,
|
||||
Dynamic,
|
||||
}
|
||||
|
||||
/// This method traverses the structure of `ty`, trying to find an
|
||||
@ -137,6 +138,10 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
|
||||
self.found = Some(NonStructuralMatchTy::Param);
|
||||
return true; // Stop visiting.
|
||||
}
|
||||
ty::Dynamic(..) => {
|
||||
self.found = Some(NonStructuralMatchTy::Dynamic);
|
||||
return true; // Stop visiting.
|
||||
}
|
||||
ty::RawPtr(..) => {
|
||||
// structural-match ignores substructure of
|
||||
// `*const _`/`*mut _`, so skip `super_visit_with`.
|
||||
|
15
src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
Normal file
15
src/test/ui/const-generics/issues/issue-63322-forbid-dyn.rs
Normal file
@ -0,0 +1,15 @@
|
||||
#![feature(const_generics)]
|
||||
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
|
||||
trait A {}
|
||||
struct B;
|
||||
impl A for B {}
|
||||
|
||||
fn test<const T: &'static dyn A>() {
|
||||
//~^ ERROR must be annotated with `#[derive(PartialEq, Eq)]` to be used
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test::<{ &B }>();
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
|
||||
--> $DIR/issue-63322-forbid-dyn.rs:1:12
|
||||
|
|
||||
LL | #![feature(const_generics)]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(incomplete_features)]` on by default
|
||||
|
||||
error[E0741]: `&'static (dyn A + 'static)` must be annotated with `#[derive(PartialEq, Eq)]` to be used as the type of a const parameter
|
||||
--> $DIR/issue-63322-forbid-dyn.rs:8:18
|
||||
|
|
||||
LL | fn test<const T: &'static dyn A>() {
|
||||
| ^^^^^^^^^^^^^^ `&'static (dyn A + 'static)` doesn't derive both `PartialEq` and `Eq`
|
||||
|
||||
error: aborting due to previous error; 1 warning emitted
|
||||
|
||||
For more information about this error, try `rustc --explain E0741`.
|
10
src/test/ui/match/issue-70972-dyn-trait.rs
Normal file
10
src/test/ui/match/issue-70972-dyn-trait.rs
Normal file
@ -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
|
||||
_ => {}
|
||||
}
|
||||
}
|
8
src/test/ui/match/issue-70972-dyn-trait.stderr
Normal file
8
src/test/ui/match/issue-70972-dyn-trait.stderr
Normal file
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user