Skip to content

Commit

Permalink
Merge pull request #427 from Areredify/unsize
Browse files Browse the repository at this point in the history
add `Unsize` trait implementation
  • Loading branch information
nikomatsakis authored Jun 9, 2020
2 parents ed5b8a2 + 4189525 commit 5b6ef58
Show file tree
Hide file tree
Showing 21 changed files with 1,593 additions and 446 deletions.
18 changes: 14 additions & 4 deletions chalk-engine/src/logic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ use crate::{
use chalk_ir::interner::Interner;
use chalk_ir::{debug, debug_heading, info, info_heading};
use chalk_ir::{
Canonical, ConstrainedSubst, Floundered, Goal, GoalData, InEnvironment, NoSolution,
Substitution, UCanonical, UniverseMap,
Canonical, ConstrainedSubst, DomainGoal, Floundered, Goal, GoalData, InEnvironment, NoSolution,
Substitution, UCanonical, UniverseMap, WhereClause,
};

type RootSearchResult<T> = Result<T, RootSearchFail>;
Expand Down Expand Up @@ -251,8 +251,18 @@ impl<I: Interner, C: Context<I>> Forest<I, C> {
) -> Table<I> {
let mut table = Table::new(goal.clone(), context.is_coinductive(&goal));
let (mut infer, subst, environment, goal) = context.instantiate_ucanonical_goal(&goal);
match goal.data(context.interner()) {
GoalData::DomainGoal(domain_goal) => {
let goal_data = goal.data(context.interner());

let is_outlives_goal = |dg: &DomainGoal<I>| {
if let DomainGoal::Holds(WhereClause::LifetimeOutlives(_)) = dg {
true
} else {
false
}
};

match goal_data {
GoalData::DomainGoal(domain_goal) if !is_outlives_goal(domain_goal) => {
match context.program_clauses(&environment, &domain_goal, &mut infer) {
Ok(clauses) => {
for clause in clauses {
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 @@ -1828,6 +1828,7 @@ impl LowerWellKnownTrait for WellKnownTrait {
Self::FnOnce => rust_ir::WellKnownTrait::FnOnce,
Self::FnMut => rust_ir::WellKnownTrait::FnMut,
Self::Fn => rust_ir::WellKnownTrait::Fn,
Self::Unsize => rust_ir::WellKnownTrait::Unsize,
}
}
}
Expand Down
14 changes: 14 additions & 0 deletions chalk-ir/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1351,6 +1351,15 @@ impl<I: Interner> WhereClause<I> {
wc => wc.cast(interner),
}
}

/// If where clause is a `TraitRef`, returns its trait id
pub fn trait_id(&self) -> Option<TraitId<I>> {
match self {
WhereClause::Implemented(trait_ref) => Some(trait_ref.trait_id),
WhereClause::AliasEq(_) => None,
WhereClause::LifetimeOutlives(_) => None,
}
}
}

impl<I: Interner> QuantifiedWhereClause<I> {
Expand All @@ -1369,6 +1378,11 @@ impl<I: Interner> QuantifiedWhereClause<I> {
pub fn into_from_env_goal(self, interner: &I) -> Binders<DomainGoal<I>> {
self.map(|wc| wc.into_from_env_goal(interner))
}

/// If the underlying where clause is a `TraitRef`, returns its trait id
pub fn trait_id(&self) -> Option<TraitId<I>> {
self.skip_binders().trait_id()
}
}

#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)]
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 @@ -72,6 +72,7 @@ pub enum WellKnownTrait {
FnOnce,
FnMut,
Fn,
Unsize,
}

#[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 @@ -55,6 +55,7 @@ WellKnownTrait: WellKnownTrait = {
"#" "[" "lang" "(" "fn_once" ")" "]" => WellKnownTrait::FnOnce,
"#" "[" "lang" "(" "fn_mut" ")" "]" => WellKnownTrait::FnMut,
"#" "[" "lang" "(" "fn" ")" "]" => WellKnownTrait::Fn,
"#" "[" "lang" "(" "unsize" ")" "]" => WellKnownTrait::Unsize,
};

StructDefn: StructDefn = {
Expand Down
4 changes: 4 additions & 0 deletions chalk-solve/src/clauses/builtin_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod clone;
mod copy;
mod fn_family;
mod sized;
mod unsize;

/// For well known traits we have special hard-coded impls, either as an
/// optimization or to enforce special rules for correctness.
Expand Down Expand Up @@ -36,6 +37,9 @@ pub fn add_builtin_program_clauses<I: Interner>(
WellKnownTrait::FnOnce | WellKnownTrait::FnMut | WellKnownTrait::Fn => {
fn_family::add_fn_trait_program_clauses(db, builder, trait_ref.trait_id, self_ty)?
}
WellKnownTrait::Unsize => {
unsize::add_unsize_program_clauses(db, builder, &trait_ref, ty)
}
// Drop impls are provided explicitly
WellKnownTrait::Drop => (),
}
Expand Down
Loading

0 comments on commit 5b6ef58

Please sign in to comment.