Skip to content

Commit 582ea06

Browse files
authored
Merge pull request #444 from nathanwhit/typename-refs
Add reference types to `TypeName`
2 parents 220953b + 5e3e1b5 commit 582ea06

File tree

11 files changed

+126
-8
lines changed

11 files changed

+126
-8
lines changed

chalk-integration/src/lowering.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1221,6 +1221,24 @@ impl LowerTy for Ty {
12211221
)?,
12221222
})
12231223
.intern(interner)),
1224+
1225+
Ty::Ref {
1226+
mutability,
1227+
lifetime,
1228+
ty,
1229+
} => Ok(chalk_ir::TyData::Apply(chalk_ir::ApplicationTy {
1230+
name: chalk_ir::TypeName::Ref(ast_mutability_to_chalk_mutability(
1231+
mutability.clone(),
1232+
)),
1233+
substitution: chalk_ir::Substitution::from(
1234+
interner,
1235+
&[
1236+
lifetime.lower(env)?.cast(interner),
1237+
ty.lower(env)?.cast(interner),
1238+
],
1239+
),
1240+
})
1241+
.intern(interner)),
12241242
}
12251243
}
12261244
}

chalk-ir/src/debug.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ impl<I: Interner> Debug for TypeName<I> {
145145
TypeName::Tuple(arity) => write!(fmt, "{:?}", arity),
146146
TypeName::OpaqueType(opaque_ty) => write!(fmt, "!{:?}", opaque_ty),
147147
TypeName::Raw(mutability) => write!(fmt, "{:?}", mutability),
148+
TypeName::Ref(mutability) => write!(fmt, "{:?}", mutability),
148149
TypeName::Error => write!(fmt, "{{error}}"),
149150
}
150151
}

chalk-ir/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ pub enum TypeName<I: Interner> {
159159
/// a raw pointer type like `*const T` or `*mut T`
160160
Raw(Mutability),
161161

162+
/// a reference type like `&T` or `&mut T`
163+
Ref(Mutability),
164+
162165
/// a placeholder for opaque types like `impl Trait`
163166
OpaqueType(OpaqueTyId<I>),
164167

chalk-parse/src/ast.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,11 @@ pub enum Ty {
197197
mutability: Mutability,
198198
ty: Box<Ty>,
199199
},
200+
Ref {
201+
mutability: Mutability,
202+
lifetime: Lifetime,
203+
ty: Box<Ty>,
204+
},
200205
}
201206

202207
#[derive(Copy, Clone, PartialEq, Eq, Debug)]

chalk-parse/src/parser.lalrpop

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,9 @@ TyWithoutFor: Ty = {
205205
<n:Id> "<" <a:Comma<Parameter>> ">" => Ty::Apply { name: n, args: a },
206206
<p:ProjectionTy> => Ty::Projection { proj: p },
207207
"(" <t:TupleOrParensInner> ")" => t,
208-
"*" <m: Mutability> <t:Ty> => Ty::Raw{ mutability: m, ty: Box::new(t) },
208+
"*" <m: RawMutability> <t:Ty> => Ty::Raw{ mutability: m, ty: Box::new(t) },
209+
"&" <l: Lifetime> "mut" <t:Ty> => Ty::Ref{ mutability: Mutability::Mut, lifetime: l, ty: Box::new(t) },
210+
"&" <l: Lifetime> <t:Ty> => Ty::Ref{ mutability: Mutability::Not, lifetime: l, ty: Box::new(t) },
209211
};
210212

211213
ScalarType: ScalarType = {
@@ -238,7 +240,7 @@ TupleOrParensInner: Ty = {
238240
() => Ty::Tuple { types: vec![] },
239241
};
240242

241-
Mutability: Mutability = {
243+
RawMutability: Mutability = {
242244
"mut" => Mutability::Mut,
243245
"const" => Mutability::Not,
244246
};

chalk-solve/src/clauses.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ fn match_type_name<I: Interner>(
411411
builder.push_fact(WellFormed::Ty(application.clone().intern(interner)))
412412
}
413413
TypeName::Raw(_) => builder.push_fact(WellFormed::Ty(application.clone().intern(interner))),
414+
TypeName::Ref(_) => builder.push_fact(WellFormed::Ty(application.clone().intern(interner))),
414415
}
415416
}
416417

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub fn add_copy_program_clauses<I: Interner>(
4141
TypeName::Tuple(arity) => {
4242
push_tuple_copy_conditions(db, builder, trait_ref, *arity, substitution)
4343
}
44-
TypeName::Raw(_) => builder.push_fact(trait_ref.clone()),
44+
TypeName::Raw(_) | TypeName::Ref(_) => builder.push_fact(trait_ref.clone()),
4545
_ => return,
4646
},
4747
TyData::Function(_) => builder.push_fact(trait_ref.clone()),

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,11 +71,12 @@ pub fn add_sized_program_clauses<I: Interner>(
7171
TypeName::Struct(struct_id) => {
7272
push_struct_sized_conditions(db, builder, trait_ref, *struct_id, substitution)
7373
}
74-
TypeName::Scalar(_) => builder.push_fact(trait_ref.clone()),
7574
TypeName::Tuple(arity) => {
7675
push_tuple_sized_conditions(db, builder, trait_ref, *arity, substitution)
7776
}
78-
TypeName::Raw(_) => builder.push_fact(trait_ref.clone()),
77+
TypeName::Scalar(_) | TypeName::Raw(_) | TypeName::Ref(_) => {
78+
builder.push_fact(trait_ref.clone())
79+
}
7980
_ => return,
8081
},
8182
TyData::Function(_) => builder.push_fact(trait_ref.clone()),

tests/lowering/mod.rs

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ fn scalars() {
471471
}
472472

473473
error_msg {
474-
"parse error: UnrecognizedToken { token: (8, Token(51, \"i32\"), 11), expected: [\"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
474+
"parse error: UnrecognizedToken { token: (8, Token(52, \"i32\"), 11), expected: [\"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
475475
}
476476
}
477477
}
@@ -495,7 +495,7 @@ fn raw_pointers() {
495495
struct *const i32 { }
496496
}
497497
error_msg {
498-
"parse error: UnrecognizedToken { token: (8, Token(7, \"*\"), 9), expected: [\"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
498+
"parse error: UnrecognizedToken { token: (8, Token(8, \"*\"), 9), expected: [\"r#\\\"([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
499499
}
500500
}
501501

@@ -505,7 +505,31 @@ fn raw_pointers() {
505505
impl Foo for *i32 { }
506506
}
507507
error_msg {
508-
"parse error: UnrecognizedToken { token: (30, Token(51, \"i32\"), 33), expected: [\"\\\"const\\\"\", \"\\\"mut\\\"\"] }"
508+
"parse error: UnrecognizedToken { token: (30, Token(52, \"i32\"), 33), expected: [\"\\\"const\\\"\", \"\\\"mut\\\"\"] }"
509+
}
510+
}
511+
}
512+
513+
#[test]
514+
fn refs() {
515+
lowering_success! {
516+
program {
517+
trait Foo { }
518+
519+
impl<'a, T> Foo for &'a T { }
520+
impl<'b, T> Foo for &'b mut T { }
521+
}
522+
}
523+
524+
lowering_error! {
525+
program {
526+
trait Foo { }
527+
528+
impl<T> Foo for &T { }
529+
}
530+
531+
error_msg {
532+
"parse error: UnrecognizedToken { token: (36, Token(1, \"T\"), 37), expected: [\"r#\\\"\\\\\\\'([A-Za-z]|_)([A-Za-z0-9]|_)*\\\"#\"] }"
509533
}
510534
}
511535
}

tests/test/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,7 @@ mod impls;
314314
mod misc;
315315
mod negation;
316316
mod projection;
317+
mod refs;
317318
mod scalars;
318319
mod tuples;
319320
mod unify;

tests/test/refs.rs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
use super::*;
2+
3+
#[test]
4+
fn refs_are_well_formed() {
5+
test! {
6+
program { }
7+
8+
goal {
9+
forall<'a, T> { WellFormed(&'a T) }
10+
} yields {
11+
"Unique; substitution [], lifetime constraints []"
12+
}
13+
}
14+
}
15+
16+
#[test]
17+
fn refs_are_sized() {
18+
test! {
19+
program {
20+
#[lang(sized)]
21+
trait Sized { }
22+
}
23+
24+
goal {
25+
forall<'a, T> { &'a T: Sized }
26+
} yields {
27+
"Unique; substitution [], lifetime constraints []"
28+
}
29+
}
30+
}
31+
32+
#[test]
33+
fn refs_are_copy() {
34+
test! {
35+
program {
36+
#[lang(copy)]
37+
trait Copy { }
38+
}
39+
40+
goal {
41+
forall<'a, T> { &'a T: Copy }
42+
} yields {
43+
"Unique; substitution [], lifetime constraints []"
44+
}
45+
}
46+
}
47+
48+
#[test]
49+
fn refs_are_clone() {
50+
test! {
51+
program {
52+
#[lang(clone)]
53+
trait Clone { }
54+
}
55+
56+
goal {
57+
forall<'a, T> { &'a T: Clone }
58+
} yields {
59+
"Unique; substitution [], lifetime constraints []"
60+
}
61+
}
62+
}

0 commit comments

Comments
 (0)