Skip to content

Commit 4827004

Browse files
Move has_structural_eq_impls provider to rustc_ty_utils
1 parent 01fbc5a commit 4827004

File tree

4 files changed

+46
-49
lines changed

4 files changed

+46
-49
lines changed

compiler/rustc_trait_selection/src/traits/mod.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -922,7 +922,6 @@ pub fn vtable_trait_upcasting_coercion_new_vptr_slot<'tcx>(
922922

923923
pub fn provide(providers: &mut ty::query::Providers) {
924924
object_safety::provide(providers);
925-
structural_match::provide(providers);
926925
*providers = ty::query::Providers {
927926
specialization_graph_of: specialize::specialization_graph_provider,
928927
specializes: specialize::specializes,

compiler/rustc_trait_selection/src/traits/structural_match.rs

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
use crate::infer::{InferCtxt, TyCtxtInferExt};
2-
use crate::traits::{ObligationCause, ObligationCtxt};
3-
41
use rustc_data_structures::fx::FxHashSet;
52
use rustc_hir as hir;
6-
use rustc_hir::lang_items::LangItem;
7-
use rustc_middle::ty::query::Providers;
83
use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor};
94
use rustc_span::Span;
105
use std::ops::ControlFlow;
@@ -59,41 +54,6 @@ pub fn search_for_adt_const_param_violation<'tcx>(
5954
.break_value()
6055
}
6156

62-
/// This method returns true if and only if `adt_ty` itself has been marked as
63-
/// eligible for structural-match: namely, if it implements both
64-
/// `StructuralPartialEq` and `StructuralEq` (which are respectively injected by
65-
/// `#[derive(PartialEq)]` and `#[derive(Eq)]`).
66-
///
67-
/// Note that this does *not* recursively check if the substructure of `adt_ty`
68-
/// implements the traits.
69-
fn type_marked_structural<'tcx>(
70-
infcx: &InferCtxt<'tcx>,
71-
adt_ty: Ty<'tcx>,
72-
cause: ObligationCause<'tcx>,
73-
) -> bool {
74-
let ocx = ObligationCtxt::new(infcx);
75-
// require `#[derive(PartialEq)]`
76-
let structural_peq_def_id =
77-
infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span));
78-
ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id);
79-
// for now, require `#[derive(Eq)]`. (Doing so is a hack to work around
80-
// the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.)
81-
let structural_teq_def_id =
82-
infcx.tcx.require_lang_item(LangItem::StructuralTeq, Some(cause.span));
83-
ocx.register_bound(cause, ty::ParamEnv::empty(), adt_ty, structural_teq_def_id);
84-
85-
// We deliberately skip *reporting* fulfillment errors (via
86-
// `report_fulfillment_errors`), for two reasons:
87-
//
88-
// 1. The error messages would mention `std::marker::StructuralPartialEq`
89-
// (a trait which is solely meant as an implementation detail
90-
// for now), and
91-
//
92-
// 2. We are sometimes doing future-incompatibility lints for
93-
// now, so we do not want unconditional errors here.
94-
ocx.select_all_or_error().is_empty()
95-
}
96-
9757
/// This implements the traversal over the structure of a given type to try to
9858
/// find instances of ADTs (specifically structs or enums) that do not implement
9959
/// the structural-match traits (`StructuralPartialEq` and `StructuralEq`).
@@ -249,11 +209,3 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> {
249209
})
250210
}
251211
}
252-
253-
pub fn provide(providers: &mut Providers) {
254-
providers.has_structural_eq_impls = |tcx, ty| {
255-
let infcx = tcx.infer_ctxt().build();
256-
let cause = ObligationCause::dummy();
257-
type_marked_structural(&infcx, ty, cause)
258-
};
259-
}

compiler/rustc_ty_utils/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ mod layout;
2929
mod layout_sanity_check;
3030
mod needs_drop;
3131
pub mod representability;
32+
mod structural_match;
3233
mod ty;
3334

3435
pub fn provide(providers: &mut Providers) {
@@ -42,4 +43,5 @@ pub fn provide(providers: &mut Providers) {
4243
representability::provide(providers);
4344
ty::provide(providers);
4445
instance::provide(providers);
46+
structural_match::provide(providers);
4547
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use rustc_hir::lang_items::LangItem;
2+
use rustc_middle::ty::query::Providers;
3+
use rustc_middle::ty::{self, Ty, TyCtxt};
4+
5+
use rustc_infer::infer::TyCtxtInferExt;
6+
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
7+
8+
/// This method returns true if and only if `adt_ty` itself has been marked as
9+
/// eligible for structural-match: namely, if it implements both
10+
/// `StructuralPartialEq` and `StructuralEq` (which are respectively injected by
11+
/// `#[derive(PartialEq)]` and `#[derive(Eq)]`).
12+
///
13+
/// Note that this does *not* recursively check if the substructure of `adt_ty`
14+
/// implements the traits.
15+
fn has_structural_eq_impls<'tcx>(tcx: TyCtxt<'tcx>, adt_ty: Ty<'tcx>) -> bool {
16+
let ref infcx = tcx.infer_ctxt().build();
17+
let cause = ObligationCause::dummy();
18+
19+
let ocx = ObligationCtxt::new(infcx);
20+
// require `#[derive(PartialEq)]`
21+
let structural_peq_def_id =
22+
infcx.tcx.require_lang_item(LangItem::StructuralPeq, Some(cause.span));
23+
ocx.register_bound(cause.clone(), ty::ParamEnv::empty(), adt_ty, structural_peq_def_id);
24+
// for now, require `#[derive(Eq)]`. (Doing so is a hack to work around
25+
// the type `for<'a> fn(&'a ())` failing to implement `Eq` itself.)
26+
let structural_teq_def_id =
27+
infcx.tcx.require_lang_item(LangItem::StructuralTeq, Some(cause.span));
28+
ocx.register_bound(cause, ty::ParamEnv::empty(), adt_ty, structural_teq_def_id);
29+
30+
// We deliberately skip *reporting* fulfillment errors (via
31+
// `report_fulfillment_errors`), for two reasons:
32+
//
33+
// 1. The error messages would mention `std::marker::StructuralPartialEq`
34+
// (a trait which is solely meant as an implementation detail
35+
// for now), and
36+
//
37+
// 2. We are sometimes doing future-incompatibility lints for
38+
// now, so we do not want unconditional errors here.
39+
ocx.select_all_or_error().is_empty()
40+
}
41+
42+
pub fn provide(providers: &mut Providers) {
43+
providers.has_structural_eq_impls = has_structural_eq_impls;
44+
}

0 commit comments

Comments
 (0)