Skip to content

Add CoerceUnsized builtin rules #607

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Sep 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 20 additions & 20 deletions book/src/clauses/well_known_traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@ Some common examples of auto traits are `Send` and `Sync`.
[coinductive_section]: ../engine/logic/coinduction.html#coinduction-and-refinement-strands

# Current state
| Type | Copy | Clone | Sized | Unsize | Drop | FnOnce/FnMut/Fn | Unpin | Generator | auto traits |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| tuple types | ✅ | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ✅ |
| structs | ⚬ | ⚬ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ✅ |
| scalar types | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| str | 📚 | 📚 | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| never type | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ✅ |
| trait objects | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ |
| functions defs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | |
| functions ptrs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | |
| raw ptrs | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| immutable refs | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| mutable refs | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| slices | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | |
| arrays | ✅ | ✅ | ✅ | ❌ | ⚬ | ⚬ | ⚬ | ⚬ | |
| closures❌ | ❌ | ❌ | ❌ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | |
| generators❌ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | ⚬ | ❌ | ❌ | ❌ |
| gen. witness❌ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
| ----------- | | | | | | | | | |
| well-formedness | ✅ | ⚬ | ✅ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ |
| Type | Copy | Clone | Sized | Unsize | CoerceUnsized | Drop | FnOnce/FnMut/Fn | Unpin | Generator | auto traits |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| tuple types | ✅ | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ✅ |
| structs | ⚬ | ⚬ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ✅ |
| scalar types | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| str | 📚 | 📚 | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| never type | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ✅ |
| trait objects | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ |
| functions defs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | |
| functions ptrs | ✅ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | |
| raw ptrs | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| immutable refs | 📚 | 📚 | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| mutable refs | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| slices | ⚬ | ⚬ | ⚬ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| arrays | ✅ | ✅ | ✅ | ❌ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | |
| closures❌ | ❌ | ❌ | ❌ | ⚬ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | |
| generators❌ | ⚬ | ⚬ | ❌ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ | ❌ | ❌ |
| gen. witness❌ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ⚬ | ❌ |
| ----------- | | | | | | | | | | |
| well-formedness | ✅ | ⚬ | ✅ | ⚬ | ✅ | ✅ | ⚬ | ⚬ | ⚬ | ⚬ |

legend:
⚬ - not applicable
Expand Down
1 change: 1 addition & 0 deletions chalk-integration/src/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1156,6 +1156,7 @@ impl Lower for WellKnownTrait {
WellKnownTrait::Fn => rust_ir::WellKnownTrait::Fn,
WellKnownTrait::Unsize => rust_ir::WellKnownTrait::Unsize,
WellKnownTrait::Unpin => rust_ir::WellKnownTrait::Unpin,
WellKnownTrait::CoerceUnsized => rust_ir::WellKnownTrait::CoerceUnsized,
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions chalk-ir/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,16 @@ where
type Interner = I;
}

impl<A, B, C, I> HasInterner for (A, B, C)
where
A: HasInterner<Interner = I>,
B: HasInterner<Interner = I>,
C: HasInterner<Interner = I>,
I: Interner,
{
type Interner = I;
}

impl<'a, T: HasInterner> HasInterner for std::slice::Iter<'a, T> {
type Interner = T::Interner;
}
11 changes: 11 additions & 0 deletions chalk-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,17 @@ impl<I: Interner> Ty<I> {
}
}

/// Returns `Some(adt_id)` if this is an ADT, `None` otherwise
pub fn adt_id(&self, interner: &I) -> Option<AdtId<I>> {
match self.data(interner) {
TyData::Apply(ApplicationTy {
name: TypeName::Adt(adt_id),
..
}) => Some(*adt_id),
_ => None,
}
}

/// True if this type contains "bound" types/lifetimes, and hence
/// needs to be shifted across binders. This is a very inefficient
/// check, intended only for debug assertions, because I am lazy.
Expand Down
1 change: 1 addition & 0 deletions chalk-parse/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ pub enum WellKnownTrait {
Fn,
Unsize,
Unpin,
CoerceUnsized,
}

#[derive(Clone, PartialEq, Eq, Debug)]
Expand Down
1 change: 1 addition & 0 deletions chalk-parse/src/parser.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ WellKnownTrait: WellKnownTrait = {
"#" "[" "lang" "(" "fn" ")" "]" => WellKnownTrait::Fn,
"#" "[" "lang" "(" "unsize" ")" "]" => WellKnownTrait::Unsize,
"#" "[" "lang" "(" "unpin" ")" "]" => WellKnownTrait::Unpin,
"#" "[" "lang" "(" "coerce_unsized" ")" "]" => WellKnownTrait::CoerceUnsized,
};

AdtRepr: Atom = "#" "[" "repr" "(" <name:Id> ")" "]" => name.str;
Expand Down
8 changes: 2 additions & 6 deletions chalk-solve/src/clauses/builtin_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,8 @@ pub fn add_builtin_program_clauses<I: Interner>(
WellKnownTrait::Unsize => {
unsize::add_unsize_program_clauses(db, builder, &trait_ref, ty)
}

// Drop impls are provided explicitly
WellKnownTrait::Drop => (),

// There are no special rules for Unpin
WellKnownTrait::Unpin => (),
// There are no builtin impls provided for the following traits:
WellKnownTrait::Unpin | WellKnownTrait::Drop | WellKnownTrait::CoerceUnsized => (),
}
Ok(())
})
Expand Down
5 changes: 1 addition & 4 deletions chalk-solve/src/coherence/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -251,10 +251,7 @@ impl<I: Interner> CoherenceSolver<'_, I> {

let canonical_goal = &goal.into_closed_goal(interner);
let mut fresh_solver = (self.solver_builder)();
let result = match fresh_solver.solve(self.db, canonical_goal) {
Some(sol) => sol.is_unique(),
None => false,
};
let result = fresh_solver.has_unique_solution(self.db, canonical_goal);

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

Expand Down
1 change: 1 addition & 0 deletions chalk-solve/src/display/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ impl<I: Interner> RenderAsRust<I> for TraitDatum<I> {
WellKnownTrait::Fn => "fn",
WellKnownTrait::Unsize => "unsize",
WellKnownTrait::Unpin => "unpin",
WellKnownTrait::CoerceUnsized => "coerce_unsized",
};
writeln!(f, "#[lang({})]", name)?;
}
Expand Down
1 change: 1 addition & 0 deletions chalk-solve/src/rust_ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ pub enum WellKnownTrait {
Fn,
Unsize,
Unpin,
CoerceUnsized,
}

chalk_ir::const_visit!(WellKnownTrait);
Expand Down
13 changes: 13 additions & 0 deletions chalk-solve/src/solve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,4 +203,17 @@ where
goal: &UCanonical<InEnvironment<Goal<I>>>,
f: &mut dyn FnMut(SubstitutionResult<Canonical<ConstrainedSubst<I>>>, bool) -> bool,
) -> bool;

/// A convenience method for when one doesn't need the actual solution,
/// only whether or not one exists.
fn has_unique_solution(
&mut self,
program: &dyn RustIrDatabase<I>,
goal: &UCanonical<InEnvironment<Goal<I>>>,
) -> bool {
match self.solve(program, goal) {
Some(sol) => sol.is_unique(),
None => false,
}
}
}
Loading