Skip to content

Commit 898c9f7

Browse files
committed
Auto merge of #49837 - nikomatsakis:chalkify-engine, r=scalexm
work towards chalkify-ing the engine This work towards creating a "all program clauses needed for this goal" query r? @scalexm
2 parents 52ed3d8 + 2c5fbe2 commit 898c9f7

30 files changed

+380
-269
lines changed

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,7 @@ define_dep_nodes!( <'tcx>
655655
[input] Features,
656656

657657
[] ProgramClausesFor(DefId),
658+
[] ProgramClausesForEnv(ParamEnv<'tcx>),
658659
[] WasmImportModuleMap(CrateNum),
659660
[] ForeignModules(CrateNum),
660661

src/librustc/hir/map/def_collector.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -107,8 +107,9 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
107107
// information we encapsulate into
108108
let def_data = match i.node {
109109
ItemKind::Impl(..) => DefPathData::Impl,
110+
ItemKind::Trait(..) => DefPathData::Trait(i.ident.name.as_str()),
110111
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
111-
ItemKind::Trait(..) | ItemKind::TraitAlias(..) |
112+
ItemKind::TraitAlias(..) |
112113
ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) =>
113114
DefPathData::TypeNs(i.ident.name.as_str()),
114115
ItemKind::Mod(..) if i.ident == keywords::Invalid.ident() => {
@@ -222,7 +223,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
222223
let def_data = match ti.node {
223224
TraitItemKind::Method(..) | TraitItemKind::Const(..) =>
224225
DefPathData::ValueNs(ti.ident.name.as_str()),
225-
TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name.as_str()),
226+
TraitItemKind::Type(..) => DefPathData::AssocTypeInTrait(ti.ident.name.as_str()),
226227
TraitItemKind::Macro(..) => return self.visit_macro_invoc(ti.id, false),
227228
};
228229

@@ -240,7 +241,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
240241
let def_data = match ii.node {
241242
ImplItemKind::Method(..) | ImplItemKind::Const(..) =>
242243
DefPathData::ValueNs(ii.ident.name.as_str()),
243-
ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name.as_str()),
244+
ImplItemKind::Type(..) => DefPathData::AssocTypeInImpl(ii.ident.name.as_str()),
244245
ImplItemKind::Macro(..) => return self.visit_macro_invoc(ii.id, false),
245246
};
246247

src/librustc/hir/map/definitions.rs

+15
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ impl DefKey {
212212
::std::mem::discriminant(data).hash(&mut hasher);
213213
match *data {
214214
DefPathData::TypeNs(name) |
215+
DefPathData::Trait(name) |
216+
DefPathData::AssocTypeInTrait(name) |
217+
DefPathData::AssocTypeInImpl(name) |
215218
DefPathData::ValueNs(name) |
216219
DefPathData::Module(name) |
217220
DefPathData::MacroDef(name) |
@@ -358,6 +361,12 @@ pub enum DefPathData {
358361
// Different kinds of items and item-like things:
359362
/// An impl
360363
Impl,
364+
/// A trait
365+
Trait(InternedString),
366+
/// An associated type **declaration** (i.e., in a trait)
367+
AssocTypeInTrait(InternedString),
368+
/// An associated type **value** (i.e., in an impl)
369+
AssocTypeInImpl(InternedString),
361370
/// Something in the type NS
362371
TypeNs(InternedString),
363372
/// Something in the value NS
@@ -639,6 +648,9 @@ impl DefPathData {
639648
use self::DefPathData::*;
640649
match *self {
641650
TypeNs(name) |
651+
Trait(name) |
652+
AssocTypeInTrait(name) |
653+
AssocTypeInImpl(name) |
642654
ValueNs(name) |
643655
Module(name) |
644656
MacroDef(name) |
@@ -663,6 +675,9 @@ impl DefPathData {
663675
use self::DefPathData::*;
664676
let s = match *self {
665677
TypeNs(name) |
678+
Trait(name) |
679+
AssocTypeInTrait(name) |
680+
AssocTypeInImpl(name) |
666681
ValueNs(name) |
667682
Module(name) |
668683
MacroDef(name) |

src/librustc/ich/impls_ty.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -1352,10 +1352,6 @@ impl_stable_hash_for!(
13521352
}
13531353
);
13541354

1355-
impl_stable_hash_for!(struct infer::canonical::QueryRegionConstraints<'tcx> {
1356-
region_outlives, ty_outlives
1357-
});
1358-
13591355
impl_stable_hash_for!(enum infer::canonical::Certainty {
13601356
Proven, Ambiguous
13611357
});
@@ -1417,6 +1413,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for traits::Goal<'tcx> {
14171413
quantifier.hash_stable(hcx, hasher);
14181414
goal.hash_stable(hcx, hasher);
14191415
},
1416+
CannotProve => { },
14201417
}
14211418
}
14221419
}

src/librustc/infer/canonical.rs

+23-48
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ use traits::{Obligation, ObligationCause, PredicateObligation};
4242
use ty::{self, CanonicalVar, Lift, Region, Slice, Ty, TyCtxt, TypeFlags};
4343
use ty::subst::{Kind, UnpackedKind};
4444
use ty::fold::{TypeFoldable, TypeFolder};
45-
use util::captures::Captures;
4645

4746
use rustc_data_structures::indexed_vec::IndexVec;
4847
use rustc_data_structures::fx::FxHashMap;
@@ -121,7 +120,7 @@ pub enum CanonicalTyVarKind {
121120
#[derive(Clone, Debug)]
122121
pub struct QueryResult<'tcx, R> {
123122
pub var_values: CanonicalVarValues<'tcx>,
124-
pub region_constraints: QueryRegionConstraints<'tcx>,
123+
pub region_constraints: Vec<QueryRegionConstraint<'tcx>>,
125124
pub certainty: Certainty,
126125
pub value: R,
127126
}
@@ -181,12 +180,7 @@ impl<'tcx, R> Canonical<'tcx, QueryResult<'tcx, R>> {
181180
}
182181
}
183182

184-
/// Subset of `RegionConstraintData` produced by trait query.
185-
#[derive(Clone, Debug, Default)]
186-
pub struct QueryRegionConstraints<'tcx> {
187-
pub region_outlives: Vec<(Region<'tcx>, Region<'tcx>)>,
188-
pub ty_outlives: Vec<(Ty<'tcx>, Region<'tcx>)>,
189-
}
183+
pub type QueryRegionConstraint<'tcx> = ty::Binder<ty::OutlivesPredicate<Kind<'tcx>, Region<'tcx>>>;
190184

191185
/// Trait implemented by values that can be canonicalized. It mainly
192186
/// serves to identify the interning table we will use.
@@ -382,35 +376,29 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
382376
&'a self,
383377
cause: &'a ObligationCause<'tcx>,
384378
param_env: ty::ParamEnv<'tcx>,
385-
unsubstituted_region_constraints: &'a QueryRegionConstraints<'tcx>,
379+
unsubstituted_region_constraints: &'a [QueryRegionConstraint<'tcx>],
386380
result_subst: &'a CanonicalVarValues<'tcx>,
387-
) -> impl Iterator<Item = PredicateObligation<'tcx>> + Captures<'gcx> + 'a {
388-
let QueryRegionConstraints {
389-
region_outlives,
390-
ty_outlives,
391-
} = unsubstituted_region_constraints;
392-
393-
let region_obligations = region_outlives.iter().map(move |(r1, r2)| {
394-
let r1 = substitute_value(self.tcx, result_subst, r1);
395-
let r2 = substitute_value(self.tcx, result_subst, r2);
396-
Obligation::new(
397-
cause.clone(),
398-
param_env,
399-
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))),
400-
)
401-
});
402-
403-
let ty_obligations = ty_outlives.iter().map(move |(t1, r2)| {
404-
let t1 = substitute_value(self.tcx, result_subst, t1);
381+
) -> impl Iterator<Item = PredicateObligation<'tcx>> + 'a {
382+
Box::new(unsubstituted_region_constraints.iter().map(move |constraint| {
383+
let ty::OutlivesPredicate(k1, r2) = constraint.skip_binder(); // restored below
384+
let k1 = substitute_value(self.tcx, result_subst, k1);
405385
let r2 = substitute_value(self.tcx, result_subst, r2);
406-
Obligation::new(
407-
cause.clone(),
408-
param_env,
409-
ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))),
410-
)
411-
});
412-
413-
region_obligations.chain(ty_obligations)
386+
match k1.unpack() {
387+
UnpackedKind::Lifetime(r1) =>
388+
Obligation::new(
389+
cause.clone(),
390+
param_env,
391+
ty::Predicate::RegionOutlives(ty::Binder(ty::OutlivesPredicate(r1, r2))),
392+
),
393+
394+
UnpackedKind::Type(t1) =>
395+
Obligation::new(
396+
cause.clone(),
397+
param_env,
398+
ty::Predicate::TypeOutlives(ty::Binder(ty::OutlivesPredicate(t1, r2))),
399+
),
400+
}
401+
})) as Box<dyn Iterator<Item = _>>
414402
}
415403

416404
/// Given two sets of values for the same set of canonical variables, unify them.
@@ -913,19 +901,6 @@ BraceStructTypeFoldableImpl! {
913901
}
914902
}
915903

916-
BraceStructTypeFoldableImpl! {
917-
impl<'tcx> TypeFoldable<'tcx> for QueryRegionConstraints<'tcx> {
918-
region_outlives, ty_outlives
919-
}
920-
}
921-
922-
BraceStructLiftImpl! {
923-
impl<'a, 'tcx> Lift<'tcx> for QueryRegionConstraints<'a> {
924-
type Lifted = QueryRegionConstraints<'tcx>;
925-
region_outlives, ty_outlives
926-
}
927-
}
928-
929904
BraceStructTypeFoldableImpl! {
930905
impl<'tcx, R> TypeFoldable<'tcx> for QueryResult<'tcx, R> {
931906
var_values, region_constraints, certainty, value

src/librustc/session/config.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
12891289
"tell the linker to strip debuginfo when building without debuginfo enabled."),
12901290
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
12911291
"make the current crate share its generic instantiations"),
1292+
chalk: bool = (false, parse_bool, [TRACKED],
1293+
"enable the experimental Chalk-based trait solving engine"),
12921294
}
12931295

12941296
pub fn default_lib_output() -> CrateType {

src/librustc/traits/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -282,13 +282,16 @@ pub enum QuantifierKind {
282282

283283
#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
284284
pub enum Goal<'tcx> {
285-
Implies(&'tcx Slice<Clause<'tcx>>, &'tcx Goal<'tcx>),
285+
Implies(Clauses<'tcx>, &'tcx Goal<'tcx>),
286286
And(&'tcx Goal<'tcx>, &'tcx Goal<'tcx>),
287287
Not(&'tcx Goal<'tcx>),
288288
DomainGoal(DomainGoal<'tcx>),
289-
Quantified(QuantifierKind, ty::Binder<&'tcx Goal<'tcx>>)
289+
Quantified(QuantifierKind, ty::Binder<&'tcx Goal<'tcx>>),
290+
CannotProve,
290291
}
291292

293+
pub type Goals<'tcx> = &'tcx Slice<Goal<'tcx>>;
294+
292295
impl<'tcx> Goal<'tcx> {
293296
pub fn from_poly_domain_goal<'a>(
294297
domain_goal: PolyDomainGoal<'tcx>,
@@ -318,6 +321,9 @@ pub enum Clause<'tcx> {
318321
ForAll(ty::Binder<ProgramClause<'tcx>>),
319322
}
320323

324+
/// Multiple clauses.
325+
pub type Clauses<'tcx> = &'tcx Slice<Clause<'tcx>>;
326+
321327
/// A "program clause" has the form `D :- G1, ..., Gn`. It is saying
322328
/// that the domain goal `D` is true if `G1...Gn` are provable. This
323329
/// is equivalent to the implication `G1..Gn => D`; we usually write
@@ -330,7 +336,7 @@ pub struct ProgramClause<'tcx> {
330336
pub goal: DomainGoal<'tcx>,
331337

332338
/// ...if we can prove these hypotheses (there may be no hypotheses at all):
333-
pub hypotheses: &'tcx Slice<Goal<'tcx>>,
339+
pub hypotheses: Goals<'tcx>,
334340
}
335341

336342
pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;

src/librustc/traits/structural_impls.rs

+2
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,7 @@ impl<'tcx> fmt::Display for traits::Goal<'tcx> {
491491
// FIXME: appropriate binder names
492492
write!(fmt, "{}<> {{ {} }}", qkind, goal.skip_binder())
493493
}
494+
CannotProve => write!(fmt, "CannotProve"),
494495
}
495496
}
496497
}
@@ -557,6 +558,7 @@ EnumTypeFoldableImpl! {
557558
(traits::Goal::Not)(goal),
558559
(traits::Goal::DomainGoal)(domain_goal),
559560
(traits::Goal::Quantified)(qkind, goal),
561+
(traits::Goal::CannotProve),
560562
}
561563
}
562564

src/librustc/ty/context.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use ty::subst::{Kind, Substs};
3838
use ty::ReprOptions;
3939
use ty::Instance;
4040
use traits;
41-
use traits::{Clause, Goal};
41+
use traits::{Clause, Clauses, Goal, Goals};
4242
use ty::{self, Ty, TypeAndMut};
4343
use ty::{TyS, TypeVariants, Slice};
4444
use ty::{AdtKind, AdtDef, ClosureSubsts, GeneratorInterior, Region, Const};
@@ -2517,15 +2517,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
25172517
}
25182518
}
25192519

2520-
pub fn intern_clauses(self, ts: &[Clause<'tcx>]) -> &'tcx Slice<Clause<'tcx>> {
2520+
pub fn intern_clauses(self, ts: &[Clause<'tcx>]) -> Clauses<'tcx> {
25212521
if ts.len() == 0 {
25222522
Slice::empty()
25232523
} else {
25242524
self._intern_clauses(ts)
25252525
}
25262526
}
25272527

2528-
pub fn intern_goals(self, ts: &[Goal<'tcx>]) -> &'tcx Slice<Goal<'tcx>> {
2528+
pub fn intern_goals(self, ts: &[Goal<'tcx>]) -> Goals<'tcx> {
25292529
if ts.len() == 0 {
25302530
Slice::empty()
25312531
} else {
@@ -2579,13 +2579,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
25792579
self.mk_substs(iter::once(s).chain(t.into_iter().cloned()).map(Kind::from))
25802580
}
25812581

2582-
pub fn mk_clauses<I: InternAs<[Clause<'tcx>],
2583-
&'tcx Slice<Clause<'tcx>>>>(self, iter: I) -> I::Output {
2582+
pub fn mk_clauses<I: InternAs<[Clause<'tcx>], Clauses<'tcx>>>(self, iter: I) -> I::Output {
25842583
iter.intern_with(|xs| self.intern_clauses(xs))
25852584
}
25862585

2587-
pub fn mk_goals<I: InternAs<[Goal<'tcx>],
2588-
&'tcx Slice<Goal<'tcx>>>>(self, iter: I) -> I::Output {
2586+
pub fn mk_goals<I: InternAs<[Goal<'tcx>], Goals<'tcx>>>(self, iter: I) -> I::Output {
25892587
iter.intern_with(|xs| self.intern_goals(xs))
25902588
}
25912589

src/librustc/ty/item_path.rs

+3
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
204204
// finer-grained distinctions, e.g. between enum/struct).
205205
data @ DefPathData::Misc |
206206
data @ DefPathData::TypeNs(..) |
207+
data @ DefPathData::Trait(..) |
208+
data @ DefPathData::AssocTypeInTrait(..) |
209+
data @ DefPathData::AssocTypeInImpl(..) |
207210
data @ DefPathData::ValueNs(..) |
208211
data @ DefPathData::Module(..) |
209212
data @ DefPathData::TypeParam(..) |

src/librustc/ty/maps/config.rs

+6
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,12 @@ impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for<'tcx> {
717717
}
718718
}
719719

720+
impl<'tcx> QueryDescription<'tcx> for queries::program_clauses_for_env<'tcx> {
721+
fn describe(_tcx: TyCtxt, _: ty::ParamEnv<'tcx>) -> String {
722+
format!("generating chalk-style clauses for param env")
723+
}
724+
}
725+
720726
impl<'tcx> QueryDescription<'tcx> for queries::wasm_import_module_map<'tcx> {
721727
fn describe(_tcx: TyCtxt, _: CrateNum) -> String {
722728
format!("wasm import module map")

src/librustc/ty/maps/keys.rs

+9
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,15 @@ impl<'tcx> Key for Ty<'tcx> {
154154
}
155155
}
156156

157+
impl<'tcx> Key for ty::ParamEnv<'tcx> {
158+
fn map_crate(&self) -> CrateNum {
159+
LOCAL_CRATE
160+
}
161+
fn default_span(&self, _: TyCtxt) -> Span {
162+
DUMMY_SP
163+
}
164+
}
165+
157166
impl<'tcx, T: Key> Key for ty::ParamEnvAnd<'tcx, T> {
158167
fn map_crate(&self) -> CrateNum {
159168
self.value.map_crate()

src/librustc/ty/maps/mod.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ use traits::query::{CanonicalProjectionGoal, CanonicalTyGoal, NoSolution};
3737
use traits::query::dropck_outlives::{DtorckConstraint, DropckOutlivesResult};
3838
use traits::query::normalize::NormalizationResult;
3939
use traits::specialization_graph;
40-
use traits::Clause;
41-
use ty::{self, CrateInherentImpls, ParamEnvAnd, Slice, Ty, TyCtxt};
40+
use traits::Clauses;
41+
use ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
4242
use ty::steal::Steal;
4343
use ty::subst::Substs;
4444
use util::nodemap::{DefIdSet, DefIdMap, ItemLocalSet};
@@ -445,7 +445,11 @@ define_maps! { <'tcx>
445445

446446
[] fn features_query: features_node(CrateNum) -> Lrc<feature_gate::Features>,
447447

448-
[] fn program_clauses_for: ProgramClausesFor(DefId) -> Lrc<&'tcx Slice<Clause<'tcx>>>,
448+
[] fn program_clauses_for: ProgramClausesFor(DefId) -> Clauses<'tcx>,
449+
450+
[] fn program_clauses_for_env: ProgramClausesForEnv(
451+
ty::ParamEnv<'tcx>
452+
) -> Clauses<'tcx>,
449453

450454
[] fn wasm_custom_sections: WasmCustomSections(CrateNum) -> Lrc<Vec<DefId>>,
451455
[] fn wasm_import_module_map: WasmImportModuleMap(CrateNum)

src/librustc/ty/maps/plumbing.rs

+1
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
978978
DepKind::DropckOutlives |
979979
DepKind::SubstituteNormalizeAndTestPredicates |
980980
DepKind::InstanceDefSizeEstimate |
981+
DepKind::ProgramClausesForEnv |
981982

982983
// This one should never occur in this context
983984
DepKind::Null => {

src/librustc/ty/mod.rs

+5
Original file line numberDiff line numberDiff line change
@@ -1138,6 +1138,11 @@ pub struct ProjectionPredicate<'tcx> {
11381138
pub type PolyProjectionPredicate<'tcx> = Binder<ProjectionPredicate<'tcx>>;
11391139

11401140
impl<'tcx> PolyProjectionPredicate<'tcx> {
1141+
/// Returns the def-id of the associated item being projected.
1142+
pub fn item_def_id(&self) -> DefId {
1143+
self.skip_binder().projection_ty.item_def_id
1144+
}
1145+
11411146
pub fn to_poly_trait_ref(&self, tcx: TyCtxt) -> PolyTraitRef<'tcx> {
11421147
// Note: unlike with TraitRef::to_poly_trait_ref(),
11431148
// self.0.trait_ref is permitted to have escaping regions.

0 commit comments

Comments
 (0)