Skip to content

Commit 8286a02

Browse files
committed
Parse #[deref], add rudimentary lang item infrastructure.
1 parent 61e90fd commit 8286a02

File tree

6 files changed

+49
-1
lines changed

6 files changed

+49
-1
lines changed

chalk-parse/src/ast.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub struct TraitFlags {
4848
pub auto: bool,
4949
pub marker: bool,
5050
pub external: bool,
51+
pub deref: bool,
5152
}
5253

5354
pub struct AssocTyDefn {

chalk-parse/src/parser.lalrpop

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Goal1: Box<Goal> = {
3838
ExternalKeyword: () = "extern";
3939
AutoKeyword: () = "#" "[" "auto" "]";
4040
MarkerKeyword: () = "#" "[" "marker" "]";
41+
DerefKeyword: () = "#" "[" "deref" "]";
4142

4243
StructDefn: StructDefn = {
4344
<external:ExternalKeyword?> "struct" <n:Id><p:Angle<ParameterKind>>
@@ -54,7 +55,7 @@ StructDefn: StructDefn = {
5455
};
5556

5657
TraitDefn: TraitDefn = {
57-
<external:ExternalKeyword?> <auto:AutoKeyword?> <marker:MarkerKeyword?> "trait" <n:Id><p:Angle<ParameterKind>>
58+
<external:ExternalKeyword?> <auto:AutoKeyword?> <marker:MarkerKeyword?> <deref:DerefKeyword?> "trait" <n:Id><p:Angle<ParameterKind>>
5859
<w:QuantifiedWhereClauses> "{" <a:AssocTyDefn*> "}" => TraitDefn
5960
{
6061
name: n,
@@ -65,6 +66,7 @@ TraitDefn: TraitDefn = {
6566
auto: auto.is_some(),
6667
marker: marker.is_some(),
6768
external: external.is_some(),
69+
deref: deref.is_some(),
6870
},
6971
}
7072
};

src/errors.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,5 +50,10 @@ error_chain! {
5050
description("could not match")
5151
display("could not match")
5252
}
53+
54+
DuplicateLangItem(item: ir::LangItem) {
55+
description("Duplicate lang item")
56+
display("Duplicate lang item `{:?}`", item)
57+
}
5358
}
5459
}

src/ir/mod.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ pub struct Program {
3838

3939
/// For each user-specified clause
4040
crate custom_clauses: Vec<ProgramClause>,
41+
42+
/// Special types and traits.
43+
crate lang_items: BTreeMap<LangItem, ItemId>,
4144
}
4245

4346
impl Program {
@@ -71,6 +74,11 @@ pub struct ProgramEnvironment {
7174
crate program_clauses: Vec<ProgramClause>,
7275
}
7376

77+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
78+
pub enum LangItem {
79+
DerefTrait,
80+
}
81+
7482
#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
7583
/// The set of assumptions we've made so far, and the current number of
7684
/// universal (forall) quantifiers we're within.
@@ -244,6 +252,7 @@ pub struct TraitFlags {
244252
crate auto: bool,
245253
crate marker: bool,
246254
crate external: bool,
255+
pub deref: bool,
247256
}
248257

249258
#[derive(Clone, Debug, PartialEq, Eq, Hash)]

src/lower/mod.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,7 @@ impl LowerProgram for Program {
172172
let mut impl_data = BTreeMap::new();
173173
let mut associated_ty_data = BTreeMap::new();
174174
let mut custom_clauses = Vec::new();
175+
let mut lang_items = BTreeMap::new();
175176
for (item, &item_id) in self.items.iter().zip(&item_ids) {
176177
let empty_env = Env {
177178
type_ids: &type_ids,
@@ -204,6 +205,16 @@ impl LowerProgram for Program {
204205
},
205206
);
206207
}
208+
209+
if d.flags.deref {
210+
use std::collections::btree_map::Entry::*;
211+
match lang_items.entry(ir::LangItem::DerefTrait) {
212+
Vacant(entry) => { entry.insert(item_id); },
213+
Occupied(_) => {
214+
bail!(ErrorKind::DuplicateLangItem(ir::LangItem::DerefTrait))
215+
}
216+
}
217+
}
207218
}
208219
Item::Impl(ref d) => {
209220
impl_data.insert(item_id, d.lower_impl(&empty_env)?);
@@ -222,6 +233,7 @@ impl LowerProgram for Program {
222233
impl_data,
223234
associated_ty_data,
224235
custom_clauses,
236+
lang_items,
225237
default_impl_data: Vec::new(),
226238
};
227239
program.add_default_impls();
@@ -903,6 +915,7 @@ impl LowerTrait for TraitDefn {
903915
auto: self.flags.auto,
904916
marker: self.flags.marker,
905917
external: self.flags.external,
918+
deref: self.flags.deref,
906919
},
907920
})
908921
})?;

src/lower/test.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -850,3 +850,21 @@ fn higher_ranked_cyclic_requirements() {
850850
}
851851
}
852852
}
853+
854+
#[test]
855+
fn deref_trait() {
856+
lowering_success! {
857+
program {
858+
#[deref] trait Deref { type Target; }
859+
}
860+
}
861+
862+
lowering_error! {
863+
program {
864+
#[deref] trait Deref { }
865+
#[deref] trait DerefDupe { }
866+
} error_msg {
867+
"Duplicate lang item `DerefTrait`"
868+
}
869+
}
870+
}

0 commit comments

Comments
 (0)