Skip to content

Commit 5bf5c7d

Browse files
committed
Handle tuples for builtin Copy and Clone traits
1 parent 4d8b6df commit 5bf5c7d

File tree

2 files changed

+83
-1
lines changed

2 files changed

+83
-1
lines changed

chalk-solve/src/clauses/builtin_traits/copy.rs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
1+
use crate::clauses::builtin_traits::needs_impl_for_tys;
12
use crate::clauses::ClauseBuilder;
23
use crate::{Interner, RustIrDatabase, TraitRef};
3-
use chalk_ir::TyData;
4+
use chalk_ir::{ApplicationTy, Substitution, TyData, TypeName};
5+
6+
fn push_tuple_copy_conditions<I: Interner>(
7+
db: &dyn RustIrDatabase<I>,
8+
builder: &mut ClauseBuilder<'_, I>,
9+
trait_ref: &TraitRef<I>,
10+
arity: usize,
11+
substitution: &Substitution<I>,
12+
) {
13+
// Empty tuples are always Copy
14+
if arity == 0 {
15+
builder.push_fact(trait_ref.clone());
16+
return;
17+
}
18+
19+
let interner = db.interner();
20+
21+
needs_impl_for_tys(
22+
db,
23+
builder,
24+
trait_ref,
25+
substitution
26+
.iter(interner)
27+
.map(|param| param.ty(interner).unwrap().clone()),
28+
);
29+
}
430

531
pub fn add_copy_program_clauses<I: Interner>(
632
db: &dyn RustIrDatabase<I>,
@@ -11,6 +37,12 @@ pub fn add_copy_program_clauses<I: Interner>(
1137
let _interner = db.interner();
1238

1339
match ty {
40+
TyData::Apply(ApplicationTy { name, substitution }) => match name {
41+
TypeName::Tuple(arity) => {
42+
push_tuple_copy_conditions(db, builder, trait_ref, *arity, substitution)
43+
}
44+
_ => return,
45+
},
1446
TyData::Function(_) => builder.push_fact(trait_ref.clone()),
1547
// TODO(areredify)
1648
// when #368 lands, extend this to handle everything accordingly

tests/test/tuples.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,3 +84,53 @@ fn tuples_are_sized() {
8484
}
8585
}
8686
}
87+
88+
#[test]
89+
fn tuples_are_copy() {
90+
test! {
91+
program {
92+
#[lang(copy)]
93+
trait Copy { }
94+
95+
trait Foo {}
96+
97+
impl Copy for u8 {}
98+
}
99+
100+
goal {
101+
(dyn Foo,): Copy
102+
} yields {
103+
"No possible solution"
104+
}
105+
106+
goal {
107+
(u8, dyn Foo): Copy
108+
} yields {
109+
"No possible solution"
110+
}
111+
112+
goal {
113+
(dyn Foo, u8): Copy
114+
} yields {
115+
"No possible solution"
116+
}
117+
118+
goal {
119+
(): Copy
120+
} yields {
121+
"Unique; substitution [], lifetime constraints []"
122+
}
123+
124+
goal {
125+
(u8,): Copy
126+
} yields {
127+
"Unique; substitution [], lifetime constraints []"
128+
}
129+
130+
goal {
131+
(u8, u8): Copy
132+
} yields {
133+
"Unique; substitution [], lifetime constraints []"
134+
}
135+
}
136+
}

0 commit comments

Comments
 (0)