Skip to content

Commit

Permalink
Auto merge of #782 - compiler-errors:tuple, r=jackh726
Browse files Browse the repository at this point in the history
Implement support for the `Tuple` trait

Necessary to due to new trait bounds required by rust-lang/compiler-team#537 / rust-lang/rust#99943.

r? `@jackh726`
  • Loading branch information
bors committed Nov 10, 2022
2 parents cadaba9 + 2b6065f commit 3b52ecd
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 1 deletion.
1 change: 1 addition & 0 deletions chalk-integration/src/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,6 +1143,7 @@ impl Lower for WellKnownTrait {
WellKnownTrait::DiscriminantKind => rust_ir::WellKnownTrait::DiscriminantKind,
WellKnownTrait::Generator => rust_ir::WellKnownTrait::Generator,
WellKnownTrait::DispatchFromDyn => rust_ir::WellKnownTrait::DispatchFromDyn,
WellKnownTrait::Tuple => rust_ir::WellKnownTrait::Tuple,
}
}
}
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 @@ -161,6 +161,7 @@ pub enum WellKnownTrait {
DiscriminantKind,
Generator,
DispatchFromDyn,
Tuple,
}

#[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 @@ -69,6 +69,7 @@ WellKnownTrait: WellKnownTrait = {
"#" "[" "lang" "(" "discriminant_kind" ")" "]" => WellKnownTrait::DiscriminantKind,
"#" "[" "lang" "(" "generator" ")" "]" => WellKnownTrait::Generator,
"#" "[" "lang" "(" "dispatch_from_dyn" ")" "]" => WellKnownTrait::DispatchFromDyn,
"#" "[" "lang" "(" "tuple_trait" ")" "]" => WellKnownTrait::Tuple,
};

AdtReprAttr: AdtReprAttr = {
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 @@ -8,6 +8,7 @@ mod discriminant_kind;
mod fn_family;
mod generator;
mod sized;
mod tuple;
mod unsize;

/// For well known traits we have special hard-coded impls, either as an
Expand Down Expand Up @@ -50,6 +51,9 @@ pub fn add_builtin_program_clauses<I: Interner>(
WellKnownTrait::Generator => {
generator::add_generator_program_clauses(db, builder, self_ty)?;
}
WellKnownTrait::Tuple => {
tuple::add_tuple_program_clauses(db, builder, self_ty)?;
}
// There are no builtin impls provided for the following traits:
WellKnownTrait::Unpin
| WellKnownTrait::Drop
Expand Down
30 changes: 30 additions & 0 deletions chalk-solve/src/clauses/builtin_traits/tuple.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use crate::clauses::ClauseBuilder;
use crate::rust_ir::WellKnownTrait;
use crate::{Interner, RustIrDatabase, TraitRef};
use chalk_ir::{Floundered, Substitution, Ty, TyKind};

/// Add implicit impl for the `Tuple` trait for all tuples
pub fn add_tuple_program_clauses<I: Interner>(
db: &dyn RustIrDatabase<I>,
builder: &mut ClauseBuilder<'_, I>,
self_ty: Ty<I>,
) -> Result<(), Floundered> {
let interner = db.interner();

match self_ty.kind(interner) {
TyKind::Tuple(..) => {
let trait_id = db.well_known_trait_id(WellKnownTrait::Tuple).unwrap();

builder.push_fact(TraitRef {
trait_id,
substitution: Substitution::from1(interner, self_ty),
});

Ok(())
}

// Tuple trait is non-enumerable
TyKind::InferenceVar(..) | TyKind::BoundVar(_) | TyKind::Alias(..) => Err(Floundered),
_ => Ok(()),
}
}
1 change: 1 addition & 0 deletions chalk-solve/src/display/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ impl<I: Interner> RenderAsRust<I> for TraitDatum<I> {
WellKnownTrait::DiscriminantKind => "discriminant_kind",
WellKnownTrait::Generator => "generator",
WellKnownTrait::DispatchFromDyn => "dispatch_from_dyn",
WellKnownTrait::Tuple => "tuple_trait",
};
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 @@ -277,6 +277,7 @@ pub enum WellKnownTrait {
DiscriminantKind,
Generator,
DispatchFromDyn,
Tuple,
}

chalk_ir::const_visit!(WellKnownTrait);
Expand Down
3 changes: 2 additions & 1 deletion chalk-solve/src/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,8 @@ where
| WellKnownTrait::Unsize
| WellKnownTrait::Sized
| WellKnownTrait::DiscriminantKind
| WellKnownTrait::Generator => false,
| WellKnownTrait::Generator
| WellKnownTrait::Tuple => false,
};

if is_legal {
Expand Down
52 changes: 52 additions & 0 deletions tests/test/tuples.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,3 +294,55 @@ fn tuples_are_wf() {
}
}
}

#[test]
fn tuples_implement_tuple_trait() {
test! {
program {
#[lang(tuple_trait)]
trait Tuple { }
}

goal {
(): Tuple
} yields {
expect![["Unique"]]
}

goal {
(u8,): Tuple
} yields {
expect![["Unique"]]
}

goal {
(i32, i32): Tuple
} yields {
expect![["Unique"]]
}

goal {
([u8],): Tuple
} yields {
expect![["Unique"]]
}

goal {
forall<T> { (T,): Tuple }
} yields {
expect![["Unique"]]
}

goal {
i32: Tuple
} yields {
expect![["No possible solution"]]
}

goal {
exists<T> { T: Tuple }
} yields {
expect![["Ambiguous; no inference guidance"]]
}
}
}

0 comments on commit 3b52ecd

Please sign in to comment.