diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index 44faed3fa9fb..14133ebc1753 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -122,37 +122,31 @@ impl<'a, 'tcx> ConstToPat<'a, 'tcx> { fn search_for_structural_match_violation(&self, ty: Ty<'tcx>) -> Option { traits::search_for_structural_match_violation(self.span, self.tcx(), ty, false).map( |non_sm_ty| { - with_no_trimmed_paths!(match non_sm_ty.kind { - traits::NonStructuralMatchTyKind::Adt(adt) => self.adt_derive_msg(adt), - traits::NonStructuralMatchTyKind::Dynamic => { + with_no_trimmed_paths!(match non_sm_ty.kind() { + ty::Adt(adt, _) => self.adt_derive_msg(*adt), + ty::Dynamic(..) => { "trait objects cannot be used in patterns".to_string() } - traits::NonStructuralMatchTyKind::Opaque => { + ty::Opaque(..) => { "opaque types cannot be used in patterns".to_string() } - traits::NonStructuralMatchTyKind::Closure => { + ty::Closure(..) => { "closures cannot be used in patterns".to_string() } - traits::NonStructuralMatchTyKind::Generator => { + ty::Generator(..) | ty::GeneratorWitness(..) => { "generators cannot be used in patterns".to_string() } - traits::NonStructuralMatchTyKind::Float => { + ty::Float(..) => { "floating-point numbers cannot be used in patterns".to_string() } - traits::NonStructuralMatchTyKind::FnPtr => { + ty::FnPtr(..) => { "function pointers cannot be used in patterns".to_string() } - traits::NonStructuralMatchTyKind::RawPtr => { + ty::RawPtr(..) => { "raw pointers cannot be used in patterns".to_string() } - traits::NonStructuralMatchTyKind::Param => { - bug!("use of a constant whose type is a parameter inside a pattern") - } - traits::NonStructuralMatchTyKind::Projection => { - bug!("use of a constant whose type is a projection inside a pattern") - } - traits::NonStructuralMatchTyKind::Foreign => { - bug!("use of a value of a foreign type inside a pattern") + _ => { + bug!("use of a value of `{non_sm_ty}` inside a pattern") } }) }, diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs index 3ef51b0c27ab..5397baefb9cf 100644 --- a/compiler/rustc_trait_selection/src/traits/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/mod.rs @@ -61,7 +61,6 @@ pub use self::specialize::specialization_graph::FutureCompatOverlapError; pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind; pub use self::specialize::{specialization_graph, translate_substs, OverlapError}; pub use self::structural_match::search_for_structural_match_violation; -pub use self::structural_match::{NonStructuralMatchTy, NonStructuralMatchTyKind}; pub use self::util::{ elaborate_obligations, elaborate_predicates, elaborate_predicates_with_span, elaborate_trait_ref, elaborate_trait_refs, diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 25a66bb9d08a..ea11670ee777 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -6,31 +6,10 @@ use rustc_data_structures::fx::FxHashSet; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; +use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor}; use rustc_span::Span; use std::ops::ControlFlow; -#[derive(Debug)] -pub struct NonStructuralMatchTy<'tcx> { - pub ty: Ty<'tcx>, - pub kind: NonStructuralMatchTyKind<'tcx>, -} - -#[derive(Debug)] -pub enum NonStructuralMatchTyKind<'tcx> { - Adt(AdtDef<'tcx>), - Param, - Dynamic, - Foreign, - Opaque, - Closure, - Generator, - Projection, - Float, - FnPtr, - RawPtr, -} - /// This method traverses the structure of `ty`, trying to find an /// instance of an ADT (i.e. struct or enum) that doesn't implement /// the structural-match traits, or a generic type parameter @@ -64,7 +43,7 @@ pub fn search_for_structural_match_violation<'tcx>( tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, valtree_semantics: bool, -) -> Option> { +) -> Option> { ty.visit_with(&mut Search { tcx, span, seen: FxHashSet::default(), valtree_semantics }) .break_value() } @@ -140,7 +119,7 @@ impl<'tcx> Search<'tcx> { } impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { - type BreakTy = NonStructuralMatchTy<'tcx>; + type BreakTy = Ty<'tcx>; fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { debug!("Search visiting ty: {:?}", ty); @@ -148,32 +127,25 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { let (adt_def, substs) = match *ty.kind() { ty::Adt(adt_def, substs) => (adt_def, substs), ty::Param(_) => { - let kind = NonStructuralMatchTyKind::Param; - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } ty::Dynamic(..) => { - let kind = NonStructuralMatchTyKind::Dynamic; - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } ty::Foreign(_) => { - let kind = NonStructuralMatchTyKind::Foreign; - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } ty::Opaque(..) => { - let kind = NonStructuralMatchTyKind::Opaque; - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } ty::Projection(..) => { - let kind = NonStructuralMatchTyKind::Projection; - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } ty::Closure(..) => { - let kind = NonStructuralMatchTyKind::Closure; - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } ty::Generator(..) | ty::GeneratorWitness(..) => { - let kind = NonStructuralMatchTyKind::Generator; - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } ty::FnDef(..) => { // Types of formals and return in `fn(_) -> _` are also irrelevant; @@ -198,10 +170,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { if !self.valtree_semantics { return ControlFlow::CONTINUE; } else { - return ControlFlow::Break(NonStructuralMatchTy { - ty, - kind: NonStructuralMatchTyKind::FnPtr, - }); + return ControlFlow::Break(ty); } } @@ -223,10 +192,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { // pointer. Therefore, one can still use `C` in a pattern. return ControlFlow::CONTINUE; } else { - return ControlFlow::Break(NonStructuralMatchTy { - ty, - kind: NonStructuralMatchTyKind::FnPtr, - }); + return ControlFlow::Break(ty); } } @@ -234,10 +200,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { if !self.valtree_semantics { return ControlFlow::CONTINUE; } else { - return ControlFlow::Break(NonStructuralMatchTy { - ty, - kind: NonStructuralMatchTyKind::Float, - }); + return ControlFlow::Break(ty); } } @@ -263,8 +226,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { if !self.type_marked_structural(ty) { debug!("Search found ty: {:?}", ty); - let kind = NonStructuralMatchTyKind::Adt(adt_def); - return ControlFlow::Break(NonStructuralMatchTy { ty, kind }); + return ControlFlow::Break(ty); } // structural-match does not care about the diff --git a/compiler/rustc_typeck/src/check/wfcheck.rs b/compiler/rustc_typeck/src/check/wfcheck.rs index 324b229fa594..3bf76ad38ee2 100644 --- a/compiler/rustc_typeck/src/check/wfcheck.rs +++ b/compiler/rustc_typeck/src/check/wfcheck.rs @@ -854,7 +854,7 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { // We use the same error code in both branches, because this is really the same // issue: we just special-case the message for type parameters to make it // clearer. - match non_structural_match_ty.ty.kind() { + match non_structural_match_ty.kind() { ty::Param(_) => { // Const parameters may not have type parameters as their types, // because we cannot be sure that the type parameter derives `PartialEq` @@ -911,10 +911,10 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) { E0741, "`{}` must be annotated with `#[derive(PartialEq, Eq)]` to be used as \ the type of a const parameter", - non_structural_match_ty.ty, + non_structural_match_ty, ); - if ty == non_structural_match_ty.ty { + if ty == non_structural_match_ty { diag.span_label( hir_ty.span, format!("`{ty}` doesn't derive both `PartialEq` and `Eq`"),