11use crate :: infer:: { InferCtxt , TyCtxtInferExt } ;
22use crate :: traits:: ObligationCause ;
3- use crate :: traits:: { self , ConstPatternStructural , TraitEngine } ;
3+ use crate :: traits:: { self , TraitEngine } ;
44
55use rustc_data_structures:: fx:: FxHashSet ;
66use rustc_hir as hir;
77use rustc_hir:: lang_items:: { StructuralPeqTraitLangItem , StructuralTeqTraitLangItem } ;
8+ use rustc_middle:: ty:: query:: Providers ;
89use rustc_middle:: ty:: { self , AdtDef , Ty , TyCtxt , TypeFoldable , TypeVisitor } ;
910use rustc_span:: Span ;
1011
@@ -41,14 +42,14 @@ pub enum NonStructuralMatchTy<'tcx> {
4142/// that arose when the requirement was not enforced completely, see
4243/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
4344pub fn search_for_structural_match_violation < ' tcx > (
44- id : hir:: HirId ,
45- span : Span ,
45+ _id : hir:: HirId ,
46+ _span : Span ,
4647 tcx : TyCtxt < ' tcx > ,
4748 ty : Ty < ' tcx > ,
4849) -> Option < NonStructuralMatchTy < ' tcx > > {
4950 // FIXME: we should instead pass in an `infcx` from the outside.
5051 tcx. infer_ctxt ( ) . enter ( |infcx| {
51- let mut search = Search { id , span , infcx, found : None , seen : FxHashSet :: default ( ) } ;
52+ let mut search = Search { infcx, found : None , seen : FxHashSet :: default ( ) } ;
5253 ty. visit_with ( & mut search) ;
5354 search. found
5455 } )
@@ -62,26 +63,25 @@ pub fn search_for_structural_match_violation<'tcx>(
6263/// Note that this does *not* recursively check if the substructure of `adt_ty`
6364/// implements the traits.
6465pub fn type_marked_structural (
65- id : hir:: HirId ,
66- span : Span ,
6766 infcx : & InferCtxt < ' _ , ' tcx > ,
6867 adt_ty : Ty < ' tcx > ,
68+ cause : ObligationCause < ' tcx > ,
6969) -> bool {
7070 let mut fulfillment_cx = traits:: FulfillmentContext :: new ( ) ;
71- let cause = ObligationCause :: new ( span, id, ConstPatternStructural ) ;
7271 // require `#[derive(PartialEq)]`
73- let structural_peq_def_id = infcx. tcx . require_lang_item ( StructuralPeqTraitLangItem , Some ( span) ) ;
72+ let structural_peq_def_id =
73+ infcx. tcx . require_lang_item ( StructuralPeqTraitLangItem , Some ( cause. span ) ) ;
7474 fulfillment_cx. register_bound (
7575 infcx,
7676 ty:: ParamEnv :: empty ( ) ,
7777 adt_ty,
7878 structural_peq_def_id,
79- cause,
79+ cause. clone ( ) ,
8080 ) ;
8181 // for now, require `#[derive(Eq)]`. (Doing so is a hack to work around
8282 // the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.)
83- let cause = ObligationCause :: new ( span , id , ConstPatternStructural ) ;
84- let structural_teq_def_id = infcx. tcx . require_lang_item ( StructuralTeqTraitLangItem , Some ( span) ) ;
83+ let structural_teq_def_id =
84+ infcx. tcx . require_lang_item ( StructuralTeqTraitLangItem , Some ( cause . span ) ) ;
8585 fulfillment_cx. register_bound (
8686 infcx,
8787 ty:: ParamEnv :: empty ( ) ,
@@ -106,9 +106,6 @@ pub fn type_marked_structural(
106106/// find instances of ADTs (specifically structs or enums) that do not implement
107107/// the structural-match traits (`StructuralPartialEq` and `StructuralEq`).
108108struct Search < ' a , ' tcx > {
109- id : hir:: HirId ,
110- span : Span ,
111-
112109 infcx : InferCtxt < ' a , ' tcx > ,
113110
114111 /// Records first ADT that does not implement a structural-match trait.
@@ -125,7 +122,7 @@ impl Search<'a, 'tcx> {
125122 }
126123
127124 fn type_marked_structural ( & self , adt_ty : Ty < ' tcx > ) -> bool {
128- type_marked_structural ( self . id , self . span , & self . infcx , adt_ty )
125+ adt_ty . is_structural_eq_shallow ( self . tcx ( ) )
129126 }
130127}
131128
@@ -220,3 +217,12 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
220217 false
221218 }
222219}
220+
221+ pub fn provide ( providers : & mut Providers < ' _ > ) {
222+ providers. is_structural_eq_raw = |tcx, ty| {
223+ tcx. infer_ctxt ( ) . enter ( |infcx| {
224+ let cause = ObligationCause :: dummy ( ) ;
225+ type_marked_structural ( & infcx, ty, cause)
226+ } )
227+ } ;
228+ }
0 commit comments