Skip to content

Commit ea42560

Browse files
committed
Auto merge of #607 - Areredify:coerce_unsized, r=jackh726
Add CoerceUnsized builtin rules So uhh either Im missing an obvious implementation option or we are missing a necessary abstraction to do things in a reasonable manner. The problem I ran into is that there is no way to extend sequent signature and clauses *and* query the solver about them. Consider this: ``` let forall_goals: Binders<Goal<I>> = ...; gb.forall(forall_goals, |goals| { // here, the binders of `forall_goals` are "in environment", but to query the solver, you need to // return from `GoalBuilder::forall` and call the solver with the result, you can't query the solver from inside. // So, if you want to branch depending on the result of solving the `forall_goal` inside the `GoalBuilder::forall`, // you need to return (popping binders from environment), call the solver, and then reenter binders again. // At this point, it's easier to manipulate bound vars by hand (what I did in the pr). }) ``` I think an an abstraction similar to goal builder where you can call `forall` and `implies` (and these alone) to push new things to the environment, and then call solver with the goals about vars inside the environment, would be nice, (but Im not sure).
2 parents 9a3d72d + 68abca9 commit ea42560

File tree

13 files changed

+698
-150
lines changed

13 files changed

+698
-150
lines changed

book/src/clauses/well_known_traits.md

+20-20
Original file line numberDiff line numberDiff line change
@@ -28,26 +28,26 @@ Some common examples of auto traits are `Send` and `Sync`.
2828
[coinductive_section]: ../engine/logic/coinduction.html#coinduction-and-refinement-strands
2929

3030
# Current state
31-
| Type | Copy | Clone | Sized | Unsize | Drop | FnOnce/FnMut/Fn | Unpin | Generator | auto traits |
32-
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
33-
| tuple types ||||||||||
34-
| structs ||||||||||
35-
| scalar types | 📚 | 📚 |||| ||| |
36-
| str | 📚 | 📚 |||| ||| |
37-
| never type | 📚 | 📚 ||||| |||
38-
| trait objects ||||||||||
39-
| functions defs |||||| ||| |
40-
| functions ptrs |||||| ||| |
41-
| raw ptrs | 📚 | 📚 |||| ||| |
42-
| immutable refs | 📚 | 📚 |||| ||| |
43-
| mutable refs |||||| ||| |
44-
| slices ||||||| || |
45-
| arrays ||||||| || |
46-
| closures❌ |||||| ||| |
47-
| generators❌ ||||||||||
48-
| gen. witness❌ ||||||||||
49-
| ----------- | | | | | | | | | |
50-
| well-formedness ||||||||||
31+
| Type | Copy | Clone | Sized | Unsize | CoerceUnsized | Drop | FnOnce/FnMut/Fn | Unpin | Generator | auto traits |
32+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
33+
| tuple types ||||| | |||||
34+
| structs ||||| | |||||
35+
| scalar types | 📚 | 📚 ||| || ||| |
36+
| str | 📚 | 📚 ||| || ||| |
37+
| never type | 📚 | 📚 ||| | || || |
38+
| trait objects ||||| ||||||
39+
| functions defs ||||| || ||| |
40+
| functions ptrs ||||| || ||| |
41+
| raw ptrs | 📚 | 📚 ||| || ||| |
42+
| immutable refs | 📚 | 📚 ||| || ||| |
43+
| mutable refs ||||| || ||| |
44+
| slices ||||| | |||| |
45+
| arrays ||||| | |||| |
46+
| closures❌ ||||| || ||| |
47+
| generators❌ ||||| ||||||
48+
| gen. witness❌ ||||| ||||||
49+
| ----------- | | | | | | | | | | |
50+
| well-formedness ||||| ||||||
5151

5252
legend:
5353
⚬ - not applicable

chalk-integration/src/lowering.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1156,6 +1156,7 @@ impl Lower for WellKnownTrait {
11561156
WellKnownTrait::Fn => rust_ir::WellKnownTrait::Fn,
11571157
WellKnownTrait::Unsize => rust_ir::WellKnownTrait::Unsize,
11581158
WellKnownTrait::Unpin => rust_ir::WellKnownTrait::Unpin,
1159+
WellKnownTrait::CoerceUnsized => rust_ir::WellKnownTrait::CoerceUnsized,
11591160
}
11601161
}
11611162
}

chalk-ir/src/interner.rs

+10
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,16 @@ where
726726
type Interner = I;
727727
}
728728

729+
impl<A, B, C, I> HasInterner for (A, B, C)
730+
where
731+
A: HasInterner<Interner = I>,
732+
B: HasInterner<Interner = I>,
733+
C: HasInterner<Interner = I>,
734+
I: Interner,
735+
{
736+
type Interner = I;
737+
}
738+
729739
impl<'a, T: HasInterner> HasInterner for std::slice::Iter<'a, T> {
730740
type Interner = T::Interner;
731741
}

chalk-ir/src/lib.rs

+11
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,17 @@ impl<I: Interner> Ty<I> {
477477
}
478478
}
479479

480+
/// Returns `Some(adt_id)` if this is an ADT, `None` otherwise
481+
pub fn adt_id(&self, interner: &I) -> Option<AdtId<I>> {
482+
match self.data(interner) {
483+
TyData::Apply(ApplicationTy {
484+
name: TypeName::Adt(adt_id),
485+
..
486+
}) => Some(*adt_id),
487+
_ => None,
488+
}
489+
}
490+
480491
/// True if this type contains "bound" types/lifetimes, and hence
481492
/// needs to be shifted across binders. This is a very inefficient
482493
/// check, intended only for debug assertions, because I am lazy.

chalk-parse/src/ast.rs

+1
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ pub enum WellKnownTrait {
127127
Fn,
128128
Unsize,
129129
Unpin,
130+
CoerceUnsized,
130131
}
131132

132133
#[derive(Clone, PartialEq, Eq, Debug)]

chalk-parse/src/parser.lalrpop

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ WellKnownTrait: WellKnownTrait = {
6363
"#" "[" "lang" "(" "fn" ")" "]" => WellKnownTrait::Fn,
6464
"#" "[" "lang" "(" "unsize" ")" "]" => WellKnownTrait::Unsize,
6565
"#" "[" "lang" "(" "unpin" ")" "]" => WellKnownTrait::Unpin,
66+
"#" "[" "lang" "(" "coerce_unsized" ")" "]" => WellKnownTrait::CoerceUnsized,
6667
};
6768

6869
AdtRepr: Atom = "#" "[" "repr" "(" <name:Id> ")" "]" => name.str;

chalk-solve/src/clauses/builtin_traits.rs

+2-6
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,8 @@ pub fn add_builtin_program_clauses<I: Interner>(
4141
WellKnownTrait::Unsize => {
4242
unsize::add_unsize_program_clauses(db, builder, &trait_ref, ty)
4343
}
44-
45-
// Drop impls are provided explicitly
46-
WellKnownTrait::Drop => (),
47-
48-
// There are no special rules for Unpin
49-
WellKnownTrait::Unpin => (),
44+
// There are no builtin impls provided for the following traits:
45+
WellKnownTrait::Unpin | WellKnownTrait::Drop | WellKnownTrait::CoerceUnsized => (),
5046
}
5147
Ok(())
5248
})

chalk-solve/src/coherence/solve.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,7 @@ impl<I: Interner> CoherenceSolver<'_, I> {
251251

252252
let canonical_goal = &goal.into_closed_goal(interner);
253253
let mut fresh_solver = (self.solver_builder)();
254-
let result = match fresh_solver.solve(self.db, canonical_goal) {
255-
Some(sol) => sol.is_unique(),
256-
None => false,
257-
};
254+
let result = fresh_solver.has_unique_solution(self.db, canonical_goal);
258255

259256
debug!("specializes: result = {:?}", result);
260257

chalk-solve/src/display/items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ impl<I: Interner> RenderAsRust<I> for TraitDatum<I> {
194194
WellKnownTrait::Fn => "fn",
195195
WellKnownTrait::Unsize => "unsize",
196196
WellKnownTrait::Unpin => "unpin",
197+
WellKnownTrait::CoerceUnsized => "coerce_unsized",
197198
};
198199
writeln!(f, "#[lang({})]", name)?;
199200
}

chalk-solve/src/rust_ir.rs

+1
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,7 @@ pub enum WellKnownTrait {
270270
Fn,
271271
Unsize,
272272
Unpin,
273+
CoerceUnsized,
273274
}
274275

275276
chalk_ir::const_visit!(WellKnownTrait);

chalk-solve/src/solve.rs

+13
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,17 @@ where
203203
goal: &UCanonical<InEnvironment<Goal<I>>>,
204204
f: &mut dyn FnMut(SubstitutionResult<Canonical<ConstrainedSubst<I>>>, bool) -> bool,
205205
) -> bool;
206+
207+
/// A convenience method for when one doesn't need the actual solution,
208+
/// only whether or not one exists.
209+
fn has_unique_solution(
210+
&mut self,
211+
program: &dyn RustIrDatabase<I>,
212+
goal: &UCanonical<InEnvironment<Goal<I>>>,
213+
) -> bool {
214+
match self.solve(program, goal) {
215+
Some(sol) => sol.is_unique(),
216+
None => false,
217+
}
218+
}
206219
}

0 commit comments

Comments
 (0)