1
1
use crate :: infer:: { InferCtxt , TyCtxtInferExt } ;
2
2
use crate :: traits:: ObligationCause ;
3
- use crate :: traits:: { self , ConstPatternStructural , TraitEngine } ;
3
+ use crate :: traits:: { self , TraitEngine } ;
4
4
5
5
use rustc_data_structures:: fx:: FxHashSet ;
6
6
use rustc_hir as hir;
7
7
use rustc_hir:: lang_items:: { StructuralPeqTraitLangItem , StructuralTeqTraitLangItem } ;
8
+ use rustc_middle:: ty:: query:: Providers ;
8
9
use rustc_middle:: ty:: { self , AdtDef , Ty , TyCtxt , TypeFoldable , TypeVisitor } ;
9
10
use rustc_span:: Span ;
10
11
@@ -45,14 +46,14 @@ pub enum NonStructuralMatchTy<'tcx> {
45
46
/// that arose when the requirement was not enforced completely, see
46
47
/// Rust RFC 1445, rust-lang/rust#61188, and rust-lang/rust#62307.
47
48
pub fn search_for_structural_match_violation < ' tcx > (
48
- id : hir:: HirId ,
49
+ _id : hir:: HirId ,
49
50
span : Span ,
50
51
tcx : TyCtxt < ' tcx > ,
51
52
ty : Ty < ' tcx > ,
52
53
) -> Option < NonStructuralMatchTy < ' tcx > > {
53
54
// FIXME: we should instead pass in an `infcx` from the outside.
54
55
tcx. infer_ctxt ( ) . enter ( |infcx| {
55
- let mut search = Search { id , span, infcx , found : None , seen : FxHashSet :: default ( ) } ;
56
+ let mut search = Search { infcx , span, found : None , seen : FxHashSet :: default ( ) } ;
56
57
ty. visit_with ( & mut search) ;
57
58
search. found
58
59
} )
@@ -65,27 +66,26 @@ pub fn search_for_structural_match_violation<'tcx>(
65
66
///
66
67
/// Note that this does *not* recursively check if the substructure of `adt_ty`
67
68
/// implements the traits.
68
- pub fn type_marked_structural (
69
- id : hir:: HirId ,
70
- span : Span ,
69
+ fn type_marked_structural (
71
70
infcx : & InferCtxt < ' _ , ' tcx > ,
72
71
adt_ty : Ty < ' tcx > ,
72
+ cause : ObligationCause < ' tcx > ,
73
73
) -> bool {
74
74
let mut fulfillment_cx = traits:: FulfillmentContext :: new ( ) ;
75
- let cause = ObligationCause :: new ( span, id, ConstPatternStructural ) ;
76
75
// require `#[derive(PartialEq)]`
77
- let structural_peq_def_id = infcx. tcx . require_lang_item ( StructuralPeqTraitLangItem , Some ( span) ) ;
76
+ let structural_peq_def_id =
77
+ infcx. tcx . require_lang_item ( StructuralPeqTraitLangItem , Some ( cause. span ) ) ;
78
78
fulfillment_cx. register_bound (
79
79
infcx,
80
80
ty:: ParamEnv :: empty ( ) ,
81
81
adt_ty,
82
82
structural_peq_def_id,
83
- cause,
83
+ cause. clone ( ) ,
84
84
) ;
85
85
// for now, require `#[derive(Eq)]`. (Doing so is a hack to work around
86
86
// the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.)
87
- let cause = ObligationCause :: new ( span , id , ConstPatternStructural ) ;
88
- let structural_teq_def_id = infcx. tcx . require_lang_item ( StructuralTeqTraitLangItem , Some ( span) ) ;
87
+ let structural_teq_def_id =
88
+ infcx. tcx . require_lang_item ( StructuralTeqTraitLangItem , Some ( cause . span ) ) ;
89
89
fulfillment_cx. register_bound (
90
90
infcx,
91
91
ty:: ParamEnv :: empty ( ) ,
@@ -110,7 +110,6 @@ pub fn type_marked_structural(
110
110
/// find instances of ADTs (specifically structs or enums) that do not implement
111
111
/// the structural-match traits (`StructuralPartialEq` and `StructuralEq`).
112
112
struct Search < ' a , ' tcx > {
113
- id : hir:: HirId ,
114
113
span : Span ,
115
114
116
115
infcx : InferCtxt < ' a , ' tcx > ,
@@ -129,7 +128,7 @@ impl Search<'a, 'tcx> {
129
128
}
130
129
131
130
fn type_marked_structural ( & self , adt_ty : Ty < ' tcx > ) -> bool {
132
- type_marked_structural ( self . id , self . span , & self . infcx , adt_ty )
131
+ adt_ty . is_structural_eq_shallow ( self . tcx ( ) )
133
132
}
134
133
}
135
134
@@ -266,3 +265,12 @@ impl<'a, 'tcx> TypeVisitor<'tcx> for Search<'a, 'tcx> {
266
265
false
267
266
}
268
267
}
268
+
269
+ pub fn provide ( providers : & mut Providers < ' _ > ) {
270
+ providers. has_structural_eq_impls = |tcx, ty| {
271
+ tcx. infer_ctxt ( ) . enter ( |infcx| {
272
+ let cause = ObligationCause :: dummy ( ) ;
273
+ type_marked_structural ( & infcx, ty, cause)
274
+ } )
275
+ } ;
276
+ }
0 commit comments