Skip to content

Commit fb9d1d0

Browse files
Uplift inspect into rustc_type_ir
1 parent cf86088 commit fb9d1d0

File tree

20 files changed

+395
-315
lines changed

20 files changed

+395
-315
lines changed

compiler/rustc_middle/src/arena.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ macro_rules! arena_types {
6161
[] dtorck_constraint: rustc_middle::traits::query::DropckConstraint<'tcx>,
6262
[] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
6363
[] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
64-
[] canonical_goal_evaluation: rustc_middle::traits::solve::inspect::GoalEvaluationStep<'tcx>,
64+
[] canonical_goal_evaluation: rustc_next_trait_solver::solve::inspect::GoalEvaluationStep<rustc_middle::ty::TyCtxt<'tcx>>,
6565
[] query_region_constraints: rustc_middle::infer::canonical::QueryRegionConstraints<'tcx>,
6666
[] type_op_subtype:
6767
rustc_middle::infer::canonical::Canonical<'tcx,

compiler/rustc_middle/src/traits/mod.rs

+2-27
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ pub mod specialization_graph;
99
mod structural_impls;
1010
pub mod util;
1111

12-
use crate::infer::canonical::Canonical;
1312
use crate::mir::ConstraintCategory;
1413
use crate::ty::abstract_const::NotConstEvaluatable;
1514
use crate::ty::GenericArgsRef;
@@ -32,6 +31,8 @@ use std::borrow::Cow;
3231
use std::hash::{Hash, Hasher};
3332

3433
pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
34+
// FIXME: Remove this import and import via `solve::`
35+
pub use rustc_next_trait_solver::solve::BuiltinImplSource;
3536

3637
/// Depending on the stage of compilation, we want projection to be
3738
/// more or less conservative.
@@ -736,32 +737,6 @@ pub struct ImplSourceUserDefinedData<'tcx, N> {
736737
pub nested: Vec<N>,
737738
}
738739

739-
#[derive(Copy, Clone, PartialEq, Eq, TyEncodable, TyDecodable, HashStable, Debug)]
740-
pub enum BuiltinImplSource {
741-
/// Some builtin impl we don't need to differentiate. This should be used
742-
/// unless more specific information is necessary.
743-
Misc,
744-
/// A builtin impl for trait objects.
745-
///
746-
/// The vtable is formed by concatenating together the method lists of
747-
/// the base object trait and all supertraits, pointers to supertrait vtable will
748-
/// be provided when necessary; this is the start of `upcast_trait_ref`'s methods
749-
/// in that vtable.
750-
Object { vtable_base: usize },
751-
/// The vtable is formed by concatenating together the method lists of
752-
/// the base object trait and all supertraits, pointers to supertrait vtable will
753-
/// be provided when necessary; this is the position of `upcast_trait_ref`'s vtable
754-
/// within that vtable.
755-
TraitUpcasting { vtable_vptr_slot: Option<usize> },
756-
/// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`.
757-
///
758-
/// This needs to be a separate variant as it is still unstable and we need to emit
759-
/// a feature error when using it on stable.
760-
TupleUnsizing,
761-
}
762-
763-
TrivialTypeTraversalImpls! { BuiltinImplSource }
764-
765740
#[derive(Clone, Debug, PartialEq, Eq, Hash, HashStable, PartialOrd, Ord)]
766741
pub enum ObjectSafetyViolation {
767742
/// `Self: Sized` declared on the trait.

compiler/rustc_middle/src/traits/query.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use crate::ty::GenericArg;
1212
use crate::ty::{self, Ty, TyCtxt};
1313
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
1414
use rustc_span::Span;
15+
// FIXME: Remove this import and import via `traits::solve`.
16+
pub use rustc_next_trait_solver::solve::NoSolution;
1517

1618
pub mod type_op {
1719
use crate::ty::fold::TypeFoldable;
@@ -89,9 +91,6 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
8991
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
9092
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
9193

92-
#[derive(Copy, Clone, Debug, Hash, HashStable, PartialEq, Eq)]
93-
pub struct NoSolution;
94-
9594
impl<'tcx> From<TypeError<'tcx>> for NoSolution {
9695
fn from(_: TypeError<'tcx>) -> NoSolution {
9796
NoSolution

compiler/rustc_middle/src/traits/solve.rs

+5-152
Original file line numberDiff line numberDiff line change
@@ -3,92 +3,22 @@ use rustc_data_structures::intern::Interned;
33
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
44
use rustc_next_trait_solver::solve as ir_solve;
55
pub use rustc_next_trait_solver::solve::*;
6-
use rustc_span::def_id::DefId;
76

8-
use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
9-
use crate::traits::query::NoSolution;
10-
use crate::traits::Canonical;
7+
use crate::infer::canonical::QueryRegionConstraints;
118
use crate::ty::{
129
self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
1310
};
1411

15-
use super::BuiltinImplSource;
16-
1712
mod cache;
18-
pub mod inspect;
1913

2014
pub use cache::{CacheData, EvaluationCache};
2115

2216
pub type Goal<'tcx, P> = ir_solve::Goal<TyCtxt<'tcx>, P>;
2317
pub type QueryInput<'tcx, P> = ir_solve::QueryInput<TyCtxt<'tcx>, P>;
24-
25-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
26-
pub struct Response<'tcx> {
27-
pub certainty: Certainty,
28-
pub var_values: CanonicalVarValues<'tcx>,
29-
/// Additional constraints returned by this query.
30-
pub external_constraints: ExternalConstraints<'tcx>,
31-
}
32-
33-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
34-
pub enum Certainty {
35-
Yes,
36-
Maybe(MaybeCause),
37-
}
38-
39-
impl Certainty {
40-
pub const AMBIGUOUS: Certainty = Certainty::Maybe(MaybeCause::Ambiguity);
41-
42-
/// Use this function to merge the certainty of multiple nested subgoals.
43-
///
44-
/// Given an impl like `impl<T: Foo + Bar> Baz for T {}`, we have 2 nested
45-
/// subgoals whenever we use the impl as a candidate: `T: Foo` and `T: Bar`.
46-
/// If evaluating `T: Foo` results in ambiguity and `T: Bar` results in
47-
/// success, we merge these two responses. This results in ambiguity.
48-
///
49-
/// If we unify ambiguity with overflow, we return overflow. This doesn't matter
50-
/// inside of the solver as we do not distinguish ambiguity from overflow. It does
51-
/// however matter for diagnostics. If `T: Foo` resulted in overflow and `T: Bar`
52-
/// in ambiguity without changing the inference state, we still want to tell the
53-
/// user that `T: Baz` results in overflow.
54-
pub fn unify_with(self, other: Certainty) -> Certainty {
55-
match (self, other) {
56-
(Certainty::Yes, Certainty::Yes) => Certainty::Yes,
57-
(Certainty::Yes, Certainty::Maybe(_)) => other,
58-
(Certainty::Maybe(_), Certainty::Yes) => self,
59-
(Certainty::Maybe(a), Certainty::Maybe(b)) => Certainty::Maybe(a.unify_with(b)),
60-
}
61-
}
62-
63-
pub const fn overflow(suggest_increasing_limit: bool) -> Certainty {
64-
Certainty::Maybe(MaybeCause::Overflow { suggest_increasing_limit })
65-
}
66-
}
67-
68-
/// Why we failed to evaluate a goal.
69-
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
70-
pub enum MaybeCause {
71-
/// We failed due to ambiguity. This ambiguity can either
72-
/// be a true ambiguity, i.e. there are multiple different answers,
73-
/// or we hit a case where we just don't bother, e.g. `?x: Trait` goals.
74-
Ambiguity,
75-
/// We gave up due to an overflow, most often by hitting the recursion limit.
76-
Overflow { suggest_increasing_limit: bool },
77-
}
78-
79-
impl MaybeCause {
80-
fn unify_with(self, other: MaybeCause) -> MaybeCause {
81-
match (self, other) {
82-
(MaybeCause::Ambiguity, MaybeCause::Ambiguity) => MaybeCause::Ambiguity,
83-
(MaybeCause::Ambiguity, MaybeCause::Overflow { .. }) => other,
84-
(MaybeCause::Overflow { .. }, MaybeCause::Ambiguity) => self,
85-
(
86-
MaybeCause::Overflow { suggest_increasing_limit: a },
87-
MaybeCause::Overflow { suggest_increasing_limit: b },
88-
) => MaybeCause::Overflow { suggest_increasing_limit: a || b },
89-
}
90-
}
91-
}
18+
pub type QueryResult<'tcx> = ir_solve::QueryResult<TyCtxt<'tcx>>;
19+
pub type CandidateSource<'tcx> = ir_solve::CandidateSource<TyCtxt<'tcx>>;
20+
pub type CanonicalInput<'tcx, P = ty::Predicate<'tcx>> = ir_solve::CanonicalInput<TyCtxt<'tcx>, P>;
21+
pub type CanonicalResponse<'tcx> = ir_solve::CanonicalResponse<TyCtxt<'tcx>>;
9222

9323
/// Additional constraints returned on success.
9424
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default)]
@@ -107,18 +37,6 @@ impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
10737
}
10838
}
10939

110-
pub type CanonicalInput<'tcx, T = ty::Predicate<'tcx>> = Canonical<'tcx, QueryInput<'tcx, T>>;
111-
112-
pub type CanonicalResponse<'tcx> = Canonical<'tcx, Response<'tcx>>;
113-
114-
/// The result of evaluating a canonical query.
115-
///
116-
/// FIXME: We use a different type than the existing canonical queries. This is because
117-
/// we need to add a `Certainty` for `overflow` and may want to restructure this code without
118-
/// having to worry about changes to currently used code. Once we've made progress on this
119-
/// solver, merge the two responses again.
120-
pub type QueryResult<'tcx> = Result<CanonicalResponse<'tcx>, NoSolution>;
121-
12240
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
12341
pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);
12442

@@ -225,68 +143,3 @@ impl<'tcx> TypeVisitable<TyCtxt<'tcx>> for PredefinedOpaques<'tcx> {
225143
self.opaque_types.visit_with(visitor)
226144
}
227145
}
228-
229-
/// Possible ways the given goal can be proven.
230-
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
231-
pub enum CandidateSource {
232-
/// A user written impl.
233-
///
234-
/// ## Examples
235-
///
236-
/// ```rust
237-
/// fn main() {
238-
/// let x: Vec<u32> = Vec::new();
239-
/// // This uses the impl from the standard library to prove `Vec<T>: Clone`.
240-
/// let y = x.clone();
241-
/// }
242-
/// ```
243-
Impl(DefId),
244-
/// A builtin impl generated by the compiler. When adding a new special
245-
/// trait, try to use actual impls whenever possible. Builtin impls should
246-
/// only be used in cases where the impl cannot be manually be written.
247-
///
248-
/// Notable examples are auto traits, `Sized`, and `DiscriminantKind`.
249-
/// For a list of all traits with builtin impls, check out the
250-
/// `EvalCtxt::assemble_builtin_impl_candidates` method.
251-
BuiltinImpl(BuiltinImplSource),
252-
/// An assumption from the environment.
253-
///
254-
/// More precisely we've used the `n-th` assumption in the `param_env`.
255-
///
256-
/// ## Examples
257-
///
258-
/// ```rust
259-
/// fn is_clone<T: Clone>(x: T) -> (T, T) {
260-
/// // This uses the assumption `T: Clone` from the `where`-bounds
261-
/// // to prove `T: Clone`.
262-
/// (x.clone(), x)
263-
/// }
264-
/// ```
265-
ParamEnv(usize),
266-
/// If the self type is an alias type, e.g. an opaque type or a projection,
267-
/// we know the bounds on that alias to hold even without knowing its concrete
268-
/// underlying type.
269-
///
270-
/// More precisely this candidate is using the `n-th` bound in the `item_bounds` of
271-
/// the self type.
272-
///
273-
/// ## Examples
274-
///
275-
/// ```rust
276-
/// trait Trait {
277-
/// type Assoc: Clone;
278-
/// }
279-
///
280-
/// fn foo<T: Trait>(x: <T as Trait>::Assoc) {
281-
/// // We prove `<T as Trait>::Assoc` by looking at the bounds on `Assoc` in
282-
/// // in the trait definition.
283-
/// let _y = x.clone();
284-
/// }
285-
/// ```
286-
AliasBound,
287-
/// A candidate that is registered only during coherence to represent some
288-
/// yet-unknown impl that could be produced downstream without violating orphan
289-
/// rules.
290-
// FIXME: Merge this with the forced ambiguity candidates, so those don't use `Misc`.
291-
CoherenceUnknowable,
292-
}

compiler/rustc_middle/src/traits/solve/cache.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ pub struct EvaluationCache<'tcx> {
1717
#[derive(PartialEq, Eq)]
1818
pub struct CacheData<'tcx> {
1919
pub result: QueryResult<'tcx>,
20-
pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep<'tcx>]>,
20+
pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep<TyCtxt<'tcx>>]>,
2121
pub reached_depth: usize,
2222
pub encountered_overflow: bool,
2323
}
@@ -28,7 +28,7 @@ impl<'tcx> EvaluationCache<'tcx> {
2828
&self,
2929
tcx: TyCtxt<'tcx>,
3030
key: CanonicalInput<'tcx>,
31-
proof_tree: Option<&'tcx [inspect::GoalEvaluationStep<'tcx>]>,
31+
proof_tree: Option<&'tcx [inspect::GoalEvaluationStep<TyCtxt<'tcx>>]>,
3232
reached_depth: usize,
3333
encountered_overflow: bool,
3434
cycle_participants: FxHashSet<CanonicalInput<'tcx>>,
@@ -105,7 +105,7 @@ struct Success<'tcx> {
105105
#[derive(Clone, Copy)]
106106
pub struct QueryData<'tcx> {
107107
pub result: QueryResult<'tcx>,
108-
pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep<'tcx>]>,
108+
pub proof_tree: Option<&'tcx [inspect::GoalEvaluationStep<TyCtxt<'tcx>>]>,
109109
}
110110

111111
/// The cache entry for a goal `CanonicalInput`.

compiler/rustc_middle/src/ty/context.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,23 @@ use std::ops::{Bound, Deref};
8989
#[allow(rustc::usage_of_ty_tykind)]
9090
impl<'tcx> Interner for TyCtxt<'tcx> {
9191
type DefId = DefId;
92-
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
93-
type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
9492
type AdtDef = ty::AdtDef<'tcx>;
93+
9594
type GenericArgs = ty::GenericArgsRef<'tcx>;
9695
type OwnItemArgs = &'tcx [ty::GenericArg<'tcx>];
9796
type GenericArg = ty::GenericArg<'tcx>;
98-
9997
type Term = ty::Term<'tcx>;
98+
10099
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
101100
type BoundVars = &'tcx List<ty::BoundVariableKind>;
102101
type BoundVar = ty::BoundVariableKind;
103102

104103
type CanonicalVars = CanonicalVarInfos<'tcx>;
104+
type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
105+
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
106+
type ExternalConstraints = ExternalConstraints<'tcx>;
107+
type GoalEvaluationSteps = &'tcx [solve::inspect::GoalEvaluationStep<TyCtxt<'tcx>>];
108+
105109
type Ty = Ty<'tcx>;
106110
type Tys = &'tcx List<Ty<'tcx>>;
107111
type FnInputTys = &'tcx [Ty<'tcx>];

compiler/rustc_trait_selection/src/solve/assembly/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(super) mod structural_traits;
2525
/// and the `result` when using the given `source`.
2626
#[derive(Debug, Clone)]
2727
pub(super) struct Candidate<'tcx> {
28-
pub(super) source: CandidateSource,
28+
pub(super) source: CandidateSource<'tcx>,
2929
pub(super) result: CanonicalResponse<'tcx>,
3030
}
3131

@@ -47,7 +47,7 @@ pub(super) trait GoalKind<'tcx>:
4747
/// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
4848
fn probe_and_match_goal_against_assumption(
4949
ecx: &mut EvalCtxt<'_, 'tcx>,
50-
source: CandidateSource,
50+
source: CandidateSource<'tcx>,
5151
goal: Goal<'tcx, Self>,
5252
assumption: ty::Clause<'tcx>,
5353
then: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> QueryResult<'tcx>,
@@ -58,7 +58,7 @@ pub(super) trait GoalKind<'tcx>:
5858
/// goal by equating it with the assumption.
5959
fn probe_and_consider_implied_clause(
6060
ecx: &mut EvalCtxt<'_, 'tcx>,
61-
parent_source: CandidateSource,
61+
parent_source: CandidateSource<'tcx>,
6262
goal: Goal<'tcx, Self>,
6363
assumption: ty::Clause<'tcx>,
6464
requirements: impl IntoIterator<Item = (GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>,
@@ -76,7 +76,7 @@ pub(super) trait GoalKind<'tcx>:
7676
/// since they're not implied by the well-formedness of the object type.
7777
fn probe_and_consider_object_bound_candidate(
7878
ecx: &mut EvalCtxt<'_, 'tcx>,
79-
source: CandidateSource,
79+
source: CandidateSource<'tcx>,
8080
goal: Goal<'tcx, Self>,
8181
assumption: ty::Clause<'tcx>,
8282
) -> Result<Candidate<'tcx>, NoSolution> {

compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ trait ResponseT<'tcx> {
4040
fn var_values(&self) -> CanonicalVarValues<'tcx>;
4141
}
4242

43-
impl<'tcx> ResponseT<'tcx> for Response<'tcx> {
43+
impl<'tcx> ResponseT<'tcx> for Response<TyCtxt<'tcx>> {
4444
fn var_values(&self) -> CanonicalVarValues<'tcx> {
4545
self.var_values
4646
}
4747
}
4848

49-
impl<'tcx, T> ResponseT<'tcx> for inspect::State<'tcx, T> {
49+
impl<'tcx, T> ResponseT<'tcx> for inspect::State<TyCtxt<'tcx>, T> {
5050
fn var_values(&self) -> CanonicalVarValues<'tcx> {
5151
self.var_values
5252
}
@@ -384,7 +384,7 @@ pub(in crate::solve) fn make_canonical_state<'tcx, T: TypeFoldable<TyCtxt<'tcx>>
384384
var_values: &[ty::GenericArg<'tcx>],
385385
max_input_universe: ty::UniverseIndex,
386386
data: T,
387-
) -> inspect::CanonicalState<'tcx, T> {
387+
) -> inspect::CanonicalState<TyCtxt<'tcx>, T> {
388388
let var_values = CanonicalVarValues { var_values: infcx.tcx.mk_args(var_values) };
389389
let state = inspect::State { var_values, data };
390390
let state = state.fold_with(&mut EagerResolver::new(infcx));
@@ -414,7 +414,7 @@ pub(in crate::solve) fn instantiate_canonical_state<'tcx, T: TypeFoldable<TyCtxt
414414
span: Span,
415415
param_env: ty::ParamEnv<'tcx>,
416416
orig_values: &mut Vec<ty::GenericArg<'tcx>>,
417-
state: inspect::CanonicalState<'tcx, T>,
417+
state: inspect::CanonicalState<TyCtxt<'tcx>, T>,
418418
) -> T {
419419
// In case any fresh inference variables have been created between `state`
420420
// and the previous instantiation, extend `orig_values` for it.

0 commit comments

Comments
 (0)