Skip to content

Commit e23ae72

Browse files
committed
Auto merge of rust-lang#126492 - compiler-errors:more-uplifting, r=lcnr
More preparation for new trait solver uplifting Getting closer to being able to uplift the whole solver 🙏 Each commit should be self-justifying. r? lcnr
2 parents fd7eefc + ff154c7 commit e23ae72

File tree

16 files changed

+222
-163
lines changed

16 files changed

+222
-163
lines changed

Diff for: compiler/rustc_middle/src/arena.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ macro_rules! arena_types {
110110
rustc_hir::def_id::DefId,
111111
rustc_middle::ty::EarlyBinder<'tcx, rustc_middle::ty::Ty<'tcx>>
112112
>,
113-
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<'tcx>,
113+
[] external_constraints: rustc_middle::traits::solve::ExternalConstraintsData<rustc_middle::ty::TyCtxt<'tcx>>,
114114
[] predefined_opaques_in_body: rustc_middle::traits::solve::PredefinedOpaquesData<'tcx>,
115115
[decode] doc_link_resolutions: rustc_hir::def::DocLinkResMap,
116116
[] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,

Diff for: compiler/rustc_middle/src/traits/mod.rs

+1-48
Original file line numberDiff line numberDiff line change
@@ -32,54 +32,7 @@ use std::hash::{Hash, Hasher};
3232

3333
pub use self::select::{EvaluationCache, EvaluationResult, OverflowError, SelectionCache};
3434
// FIXME: Remove this import and import via `solve::`
35-
pub use rustc_type_ir::solve::BuiltinImplSource;
36-
37-
/// Depending on the stage of compilation, we want projection to be
38-
/// more or less conservative.
39-
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, HashStable, Encodable, Decodable)]
40-
pub enum Reveal {
41-
/// At type-checking time, we refuse to project any associated
42-
/// type that is marked `default`. Non-`default` ("final") types
43-
/// are always projected. This is necessary in general for
44-
/// soundness of specialization. However, we *could* allow
45-
/// projections in fully-monomorphic cases. We choose not to,
46-
/// because we prefer for `default type` to force the type
47-
/// definition to be treated abstractly by any consumers of the
48-
/// impl. Concretely, that means that the following example will
49-
/// fail to compile:
50-
///
51-
/// ```compile_fail,E0308
52-
/// #![feature(specialization)]
53-
/// trait Assoc {
54-
/// type Output;
55-
/// }
56-
///
57-
/// impl<T> Assoc for T {
58-
/// default type Output = bool;
59-
/// }
60-
///
61-
/// fn main() {
62-
/// let x: <() as Assoc>::Output = true;
63-
/// }
64-
/// ```
65-
///
66-
/// We also do not reveal the hidden type of opaque types during
67-
/// type-checking.
68-
UserFacing,
69-
70-
/// At codegen time, all monomorphic projections will succeed.
71-
/// Also, `impl Trait` is normalized to the concrete type,
72-
/// which has to be already collected by type-checking.
73-
///
74-
/// NOTE: as `impl Trait`'s concrete type should *never*
75-
/// be observable directly by the user, `Reveal::All`
76-
/// should not be used by checks which may expose
77-
/// type equality or type contents to the user.
78-
/// There are some exceptions, e.g., around auto traits and
79-
/// transmute-checking, which expose some details, but
80-
/// not the whole concrete type of the `impl Trait`.
81-
All,
82-
}
35+
pub use rustc_type_ir::solve::{BuiltinImplSource, Reveal};
8336

8437
/// The reason why we incurred this obligation; used for error reporting.
8538
///

Diff for: compiler/rustc_middle/src/traits/solve.rs

+5-25
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
use rustc_ast_ir::try_visit;
22
use rustc_data_structures::intern::Interned;
3-
use rustc_macros::{HashStable, TypeFoldable, TypeVisitable};
3+
use rustc_macros::HashStable;
44
use rustc_type_ir as ir;
55
pub use rustc_type_ir::solve::*;
66

7-
use crate::infer::canonical::QueryRegionConstraints;
87
use crate::ty::{
98
self, FallibleTypeFolder, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable, TypeVisitor,
109
};
@@ -38,37 +37,18 @@ impl<'tcx> std::ops::Deref for PredefinedOpaques<'tcx> {
3837
}
3938

4039
#[derive(Debug, PartialEq, Eq, Copy, Clone, Hash, HashStable)]
41-
pub struct ExternalConstraints<'tcx>(pub(crate) Interned<'tcx, ExternalConstraintsData<'tcx>>);
40+
pub struct ExternalConstraints<'tcx>(
41+
pub(crate) Interned<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
42+
);
4243

4344
impl<'tcx> std::ops::Deref for ExternalConstraints<'tcx> {
44-
type Target = ExternalConstraintsData<'tcx>;
45+
type Target = ExternalConstraintsData<TyCtxt<'tcx>>;
4546

4647
fn deref(&self) -> &Self::Target {
4748
&self.0
4849
}
4950
}
5051

51-
/// Additional constraints returned on success.
52-
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)]
53-
pub struct ExternalConstraintsData<'tcx> {
54-
// FIXME: implement this.
55-
pub region_constraints: QueryRegionConstraints<'tcx>,
56-
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
57-
pub normalization_nested_goals: NestedNormalizationGoals<'tcx>,
58-
}
59-
60-
#[derive(Debug, PartialEq, Eq, Clone, Hash, HashStable, Default, TypeVisitable, TypeFoldable)]
61-
pub struct NestedNormalizationGoals<'tcx>(pub Vec<(GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>);
62-
impl<'tcx> NestedNormalizationGoals<'tcx> {
63-
pub fn empty() -> Self {
64-
NestedNormalizationGoals(vec![])
65-
}
66-
67-
pub fn is_empty(&self) -> bool {
68-
self.0.is_empty()
69-
}
70-
}
71-
7252
// FIXME: Having to clone `region_constraints` for folding feels bad and
7353
// probably isn't great wrt performance.
7454
//

Diff for: compiler/rustc_middle/src/ty/context.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ use std::ops::{Bound, Deref};
8888
#[allow(rustc::usage_of_ty_tykind)]
8989
impl<'tcx> Interner for TyCtxt<'tcx> {
9090
type DefId = DefId;
91+
type LocalDefId = LocalDefId;
9192
type AdtDef = ty::AdtDef<'tcx>;
9293

9394
type GenericArgs = ty::GenericArgsRef<'tcx>;
@@ -382,7 +383,7 @@ pub struct CtxtInterners<'tcx> {
382383
bound_variable_kinds: InternedSet<'tcx, List<ty::BoundVariableKind>>,
383384
layout: InternedSet<'tcx, LayoutS<FieldIdx, VariantIdx>>,
384385
adt_def: InternedSet<'tcx, AdtDefData>,
385-
external_constraints: InternedSet<'tcx, ExternalConstraintsData<'tcx>>,
386+
external_constraints: InternedSet<'tcx, ExternalConstraintsData<TyCtxt<'tcx>>>,
386387
predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>,
387388
fields: InternedSet<'tcx, List<FieldIdx>>,
388389
local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
@@ -2093,7 +2094,7 @@ direct_interners! {
20932094
const_allocation: pub mk_const_alloc(Allocation): ConstAllocation -> ConstAllocation<'tcx>,
20942095
layout: pub mk_layout(LayoutS<FieldIdx, VariantIdx>): Layout -> Layout<'tcx>,
20952096
adt_def: pub mk_adt_def_from_data(AdtDefData): AdtDef -> AdtDef<'tcx>,
2096-
external_constraints: pub mk_external_constraints(ExternalConstraintsData<'tcx>):
2097+
external_constraints: pub mk_external_constraints(ExternalConstraintsData<TyCtxt<'tcx>>):
20972098
ExternalConstraints -> ExternalConstraints<'tcx>,
20982099
predefined_opaques_in_body: pub mk_predefined_opaques_in_body(PredefinedOpaquesData<'tcx>):
20992100
PredefinedOpaques -> PredefinedOpaques<'tcx>,

Diff for: compiler/rustc_middle/src/ty/mod.rs

+1-39
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ pub use self::context::{
9494
};
9595
pub use self::instance::{Instance, InstanceDef, ReifyReason, ShortInstance, UnusedGenericParams};
9696
pub use self::list::{List, ListWithCachedTypeInfo};
97+
pub use self::opaque_types::OpaqueTypeKey;
9798
pub use self::parameterized::ParameterizedOverTcx;
9899
pub use self::pattern::{Pattern, PatternKind};
99100
pub use self::predicate::{
@@ -758,45 +759,6 @@ impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
758759
}
759760
}
760761

761-
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
762-
#[derive(TypeFoldable, TypeVisitable)]
763-
pub struct OpaqueTypeKey<'tcx> {
764-
pub def_id: LocalDefId,
765-
pub args: GenericArgsRef<'tcx>,
766-
}
767-
768-
impl<'tcx> OpaqueTypeKey<'tcx> {
769-
pub fn iter_captured_args(
770-
self,
771-
tcx: TyCtxt<'tcx>,
772-
) -> impl Iterator<Item = (usize, GenericArg<'tcx>)> {
773-
std::iter::zip(self.args, tcx.variances_of(self.def_id)).enumerate().filter_map(
774-
|(i, (arg, v))| match (arg.unpack(), v) {
775-
(_, ty::Invariant) => Some((i, arg)),
776-
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None,
777-
_ => bug!("unexpected opaque type arg variance"),
778-
},
779-
)
780-
}
781-
782-
pub fn fold_captured_lifetime_args(
783-
self,
784-
tcx: TyCtxt<'tcx>,
785-
mut f: impl FnMut(Region<'tcx>) -> Region<'tcx>,
786-
) -> Self {
787-
let Self { def_id, args } = self;
788-
let args = std::iter::zip(args, tcx.variances_of(def_id)).map(|(arg, v)| {
789-
match (arg.unpack(), v) {
790-
(ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
791-
(ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(),
792-
_ => arg,
793-
}
794-
});
795-
let args = tcx.mk_args_from_iter(args);
796-
Self { def_id, args }
797-
}
798-
}
799-
800762
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable, HashStable, TyEncodable, TyDecodable)]
801763
pub struct OpaqueHiddenType<'tcx> {
802764
/// The span of this particular definition of the opaque type. So

Diff for: compiler/rustc_middle/src/ty/opaque_types.rs

+2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use rustc_span::def_id::DefId;
77
use rustc_span::Span;
88
use tracing::{debug, instrument, trace};
99

10+
pub type OpaqueTypeKey<'tcx> = rustc_type_ir::OpaqueTypeKey<TyCtxt<'tcx>>;
11+
1012
/// Converts generic params of a TypeFoldable from one
1113
/// item's generics to another. Usually from a function's generics
1214
/// list to the opaque type's own generics.

Diff for: compiler/rustc_next_trait_solver/src/lib.rs

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
//! Crate containing the implementation of the next-generation trait solver.
2+
//!
3+
//! This crate may also contain things that are used by the old trait solver,
4+
//! but were uplifted in the process of making the new trait solver generic.
5+
//! So if you got to this crate from the old solver, it's totally normal.
6+
17
pub mod canonicalizer;
28
pub mod resolve;
39
pub mod solve;

Diff for: compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs

+38-28
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
135135
// Remove any trivial region constraints once we've resolved regions
136136
external_constraints
137137
.region_constraints
138-
.outlives
139-
.retain(|(outlives, _)| outlives.0.as_region().map_or(true, |re| re != outlives.1));
138+
.retain(|outlives| outlives.0.as_region().map_or(true, |re| re != outlives.1));
140139

141140
let canonical = Canonicalizer::canonicalize(
142141
self.infcx,
@@ -179,8 +178,8 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
179178
fn compute_external_query_constraints(
180179
&self,
181180
certainty: Certainty,
182-
normalization_nested_goals: NestedNormalizationGoals<'tcx>,
183-
) -> ExternalConstraintsData<'tcx> {
181+
normalization_nested_goals: NestedNormalizationGoals<TyCtxt<'tcx>>,
182+
) -> ExternalConstraintsData<TyCtxt<'tcx>> {
184183
// We only return region constraints once the certainty is `Yes`. This
185184
// is necessary as we may drop nested goals on ambiguity, which may result
186185
// in unconstrained inference variables in the region constraints. It also
@@ -193,30 +192,40 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
193192
// Cannot use `take_registered_region_obligations` as we may compute the response
194193
// inside of a `probe` whenever we have multiple choices inside of the solver.
195194
let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned();
196-
let mut region_constraints = self.infcx.with_region_constraints(|region_constraints| {
197-
make_query_region_constraints(
198-
self.interner(),
199-
region_obligations.iter().map(|r_o| {
200-
(r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())
201-
}),
202-
region_constraints,
203-
)
204-
});
205-
195+
let QueryRegionConstraints { outlives, member_constraints } =
196+
self.infcx.with_region_constraints(|region_constraints| {
197+
make_query_region_constraints(
198+
self.interner(),
199+
region_obligations.iter().map(|r_o| {
200+
(r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())
201+
}),
202+
region_constraints,
203+
)
204+
});
205+
assert_eq!(member_constraints, vec![]);
206206
let mut seen = FxHashSet::default();
207-
region_constraints.outlives.retain(|outlives| seen.insert(*outlives));
208-
region_constraints
207+
outlives
208+
.into_iter()
209+
.filter(|(outlives, _)| seen.insert(*outlives))
210+
.map(|(outlives, _origin)| outlives)
211+
.collect()
209212
} else {
210213
Default::default()
211214
};
212215

213-
let mut opaque_types = self.infcx.clone_opaque_types_for_query_response();
214-
// Only return opaque type keys for newly-defined opaques
215-
opaque_types.retain(|(a, _)| {
216-
self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
217-
});
218-
219-
ExternalConstraintsData { region_constraints, opaque_types, normalization_nested_goals }
216+
ExternalConstraintsData {
217+
region_constraints,
218+
opaque_types: self
219+
.infcx
220+
.clone_opaque_types_for_query_response()
221+
.into_iter()
222+
// Only return *newly defined* opaque types.
223+
.filter(|(a, _)| {
224+
self.predefined_opaques_in_body.opaque_types.iter().all(|(pa, _)| pa != a)
225+
})
226+
.collect(),
227+
normalization_nested_goals,
228+
}
220229
}
221230

222231
/// After calling a canonical query, we apply the constraints returned
@@ -232,7 +241,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
232241
param_env: ty::ParamEnv<'tcx>,
233242
original_values: Vec<ty::GenericArg<'tcx>>,
234243
response: CanonicalResponse<'tcx>,
235-
) -> (NestedNormalizationGoals<'tcx>, Certainty) {
244+
) -> (NestedNormalizationGoals<TyCtxt<'tcx>>, Certainty) {
236245
let instantiation = Self::compute_query_response_instantiation_values(
237246
self.infcx,
238247
&original_values,
@@ -369,16 +378,17 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
369378
}
370379
}
371380

372-
fn register_region_constraints(&mut self, region_constraints: &QueryRegionConstraints<'tcx>) {
373-
for &(ty::OutlivesPredicate(lhs, rhs), _) in &region_constraints.outlives {
381+
fn register_region_constraints(
382+
&mut self,
383+
outlives: &[ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>],
384+
) {
385+
for &ty::OutlivesPredicate(lhs, rhs) in outlives {
374386
match lhs.unpack() {
375387
GenericArgKind::Lifetime(lhs) => self.register_region_outlives(lhs, rhs),
376388
GenericArgKind::Type(lhs) => self.register_ty_outlives(lhs, rhs),
377389
GenericArgKind::Const(_) => bug!("const outlives: {lhs:?}: {rhs:?}"),
378390
}
379391
}
380-
381-
assert!(region_constraints.member_constraints.is_empty());
382392
}
383393

384394
fn register_new_opaque_types(&mut self, opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)]) {

Diff for: compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@ use super::inspect::ProofTreeBuilder;
2929
use super::{search_graph, GoalEvaluationKind, FIXPOINT_STEP_LIMIT};
3030
use super::{search_graph::SearchGraph, Goal};
3131
use super::{GoalSource, SolverMode};
32-
pub use select::InferCtxtSelectExt;
3332

3433
pub(super) mod canonical;
3534
mod probe;
36-
mod select;
3735

3836
pub struct EvalCtxt<'a, Infcx, I = <Infcx as InferCtxtLike>::Interner>
3937
where
@@ -339,7 +337,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
339337
goal_evaluation_kind: GoalEvaluationKind,
340338
_source: GoalSource,
341339
goal: Goal<'tcx, ty::Predicate<'tcx>>,
342-
) -> Result<(NestedNormalizationGoals<'tcx>, bool, Certainty), NoSolution> {
340+
) -> Result<(NestedNormalizationGoals<TyCtxt<'tcx>>, bool, Certainty), NoSolution> {
343341
let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
344342
let mut goal_evaluation =
345343
self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
@@ -382,7 +380,7 @@ impl<'a, 'tcx> EvalCtxt<'a, InferCtxt<'tcx>> {
382380
param_env: ty::ParamEnv<'tcx>,
383381
original_values: Vec<ty::GenericArg<'tcx>>,
384382
response: CanonicalResponse<'tcx>,
385-
) -> (NestedNormalizationGoals<'tcx>, Certainty, bool) {
383+
) -> (NestedNormalizationGoals<TyCtxt<'tcx>>, Certainty, bool) {
386384
if let Certainty::Maybe(MaybeCause::Overflow { .. }) = response.value.certainty {
387385
return (NestedNormalizationGoals::empty(), response.value.certainty, false);
388386
}

Diff for: compiler/rustc_trait_selection/src/solve/mod.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,14 @@ mod normalize;
3737
mod normalizes_to;
3838
mod project_goals;
3939
mod search_graph;
40+
mod select;
4041
mod trait_goals;
4142

42-
pub use eval_ctxt::{EvalCtxt, GenerateProofTree, InferCtxtEvalExt, InferCtxtSelectExt};
43+
pub use eval_ctxt::{EvalCtxt, GenerateProofTree, InferCtxtEvalExt};
4344
pub use fulfill::{FulfillmentCtxt, NextSolverError};
4445
pub(crate) use normalize::deeply_normalize_for_diagnostics;
4546
pub use normalize::{deeply_normalize, deeply_normalize_with_skipped_universes};
47+
pub use select::InferCtxtSelectExt;
4648

4749
/// How many fixpoint iterations we should attempt inside of the solver before bailing
4850
/// with overflow.

0 commit comments

Comments
 (0)