Skip to content

Commit 9c5b143

Browse files
committed
Make const trait aliases work in next solver
1 parent 52e3b38 commit 9c5b143

File tree

5 files changed

+45
-46
lines changed

5 files changed

+45
-46
lines changed

compiler/rustc_hir_analysis/src/collect/predicates_of.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,9 +1018,11 @@ pub(super) fn const_conditions<'tcx>(
10181018
Node::Item(item) => match item.kind {
10191019
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
10201020
hir::ItemKind::Fn { generics, .. } => (generics, None, false),
1021-
hir::ItemKind::TraitAlias(_, _, generics, supertraits)
1022-
| hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
1023-
(generics, Some((item.owner_id.def_id, supertraits)), false)
1021+
hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
1022+
(generics, Some((Some(item.owner_id.def_id), supertraits)), false)
1023+
}
1024+
hir::ItemKind::TraitAlias(_, _, generics, supertraits) => {
1025+
(generics, Some((None, supertraits)), false)
10241026
}
10251027
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
10261028
},
@@ -1076,12 +1078,14 @@ pub(super) fn const_conditions<'tcx>(
10761078
}
10771079

10781080
if let Some((def_id, supertraits)) = trait_def_id_and_supertraits {
1079-
// We've checked above that the trait is conditionally const.
1080-
bounds.push((
1081-
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id()))
1082-
.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
1083-
DUMMY_SP,
1084-
));
1081+
if let Some(def_id) = def_id {
1082+
// We've checked above that the trait is conditionally const.
1083+
bounds.push((
1084+
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id()))
1085+
.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
1086+
DUMMY_SP,
1087+
));
1088+
}
10851089

10861090
icx.lowerer().lower_bounds(
10871091
tcx.types.self_param,

compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,10 +191,35 @@ where
191191
}
192192

193193
fn consider_trait_alias_candidate(
194-
_ecx: &mut EvalCtxt<'_, D>,
195-
_goal: Goal<I, Self>,
194+
ecx: &mut EvalCtxt<'_, D>,
195+
goal: Goal<I, Self>,
196196
) -> Result<Candidate<I>, NoSolution> {
197-
unreachable!("trait aliases are never const")
197+
let cx = ecx.cx();
198+
199+
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
200+
let where_clause_bounds = cx
201+
.predicates_of(goal.predicate.def_id())
202+
.iter_instantiated(cx, goal.predicate.trait_ref.args)
203+
.map(|p| goal.with(cx, p));
204+
ecx.add_goals(GoalSource::Misc, where_clause_bounds);
205+
206+
let const_conditions = cx
207+
.const_conditions(goal.predicate.def_id())
208+
.iter_instantiated(cx, goal.predicate.trait_ref.args)
209+
.map(|bound_trait_ref| {
210+
goal.with(
211+
cx,
212+
bound_trait_ref.to_host_effect_clause(cx, goal.predicate.constness),
213+
)
214+
});
215+
// While you could think of trait aliases to have a single builtin impl
216+
// which uses its implied trait bounds as where-clauses, using
217+
// `GoalSource::ImplWhereClause` here would be incorrect, as we also
218+
// impl them, which means we're "stepping out of the impl constructor"
219+
// again. To handle this, we treat these cycles as ambiguous for now.
220+
ecx.add_goals(GoalSource::Misc, const_conditions);
221+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
222+
})
198223
}
199224

200225
fn consider_builtin_sizedness_candidates(
Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,9 @@
11
error[E0277]: the trait bound `T: [const] Baz` is not satisfied
2-
--> $DIR/trait_alias.rs:20:11
2+
--> $DIR/trait_alias.rs:22:11
33
|
44
LL | x.baz();
55
| ^^^
66

7-
error[E0277]: the trait bound `(): const Foo` is not satisfied
8-
--> $DIR/trait_alias.rs:25:19
9-
|
10-
LL | const _: () = foo(&());
11-
| --- ^^^
12-
| |
13-
| required by a bound introduced by this call
14-
|
15-
note: required by a bound in `foo`
16-
--> $DIR/trait_alias.rs:16:17
17-
|
18-
LL | const fn foo<T: [const] Foo>(x: &T) {
19-
| ^^^^^^^^^^^ required by this bound in `foo`
20-
21-
error: aborting due to 2 previous errors
7+
error: aborting due to 1 previous error
228

239
For more information about this error, try `rustc --explain E0277`.

tests/ui/consts/trait_alias.pass.stderr

Lines changed: 0 additions & 17 deletions
This file was deleted.

tests/ui/consts/trait_alias.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#![feature(trait_alias, const_trait_impl)]
22
//@ revisions: pass fail
3+
//@ compile-flags: -Znext-solver
4+
//@[pass] check-pass
35

46
const trait Bar {
57
fn bar(&self) {}
@@ -23,6 +25,5 @@ const fn foo<T: [const] Foo>(x: &T) {
2325
}
2426

2527
const _: () = foo(&());
26-
//~^ ERROR: `(): const Foo` is not satisfied
2728

2829
fn main() {}

0 commit comments

Comments
 (0)