Skip to content

Commit 63b34b6

Browse files
committed
Typecheck fields on callee.proc
1 parent 98e69a4 commit 63b34b6

1 file changed

Lines changed: 29 additions & 2 deletions

File tree

crates/dreamchecker/src/lib.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ pub enum StaticType<'o> {
3131
list: TypeRef<'o>,
3232
keys: Box<StaticType<'o>>,
3333
},
34+
Proc,
3435
}
3536

3637
impl<'o> StaticType<'o> {
@@ -43,6 +44,7 @@ impl<'o> StaticType<'o> {
4344
StaticType::None => None,
4445
StaticType::Type(t) => Some(t),
4546
StaticType::List { list, .. } => Some(list),
47+
StaticType::Proc => None,
4648
}
4749
}
4850

@@ -74,6 +76,7 @@ impl<'o> StaticType<'o> {
7476
StaticType::None => false,
7577
StaticType::Type(ty) => ty.path == "/list",
7678
StaticType::List { .. } => true,
79+
StaticType::Proc => false,
7780
}
7881
}
7982
}
@@ -1451,6 +1454,10 @@ impl<'o, 's> AnalyzeProc<'o, 's> {
14511454
}
14521455
}
14531456
}
1457+
StaticType::Proc => {
1458+
error(location, format!("iterating over a procpath which cannot be iterated"))
1459+
.register(self.context);
1460+
}
14541461
}
14551462
}
14561463
if let Some(var_type) = var_type {
@@ -1605,6 +1612,10 @@ impl<'o, 's> AnalyzeProc<'o, 's> {
16051612
}
16061613
}
16071614
}
1615+
StaticType::Proc => {
1616+
error(location, format!("iterating over a procpath which cannot be iterated"))
1617+
.register(self.context);
1618+
}
16081619
}
16091620
}
16101621
// This quite ugly but DM doesn't let you do for (var/k, var/v)
@@ -2098,8 +2109,21 @@ impl<'o, 's> AnalyzeProc<'o, 's> {
20982109
}
20992110
},
21002111
Follow::Field(kind, name) => {
2101-
if let Some(ty) = lhs.static_ty.basic_type() {
2102-
if let Some(decl) = ty.get_var_declaration(name) {
2112+
if let StaticType::Proc = lhs.static_ty {
2113+
match name.as_str() {
2114+
"type" | "name" | "desc" | "category" | "invisibility" => {},
2115+
_ => {
2116+
error(location, format!("undefined field: {name:?} on procpath"))
2117+
.register(self.context);
2118+
}
2119+
}
2120+
Analysis::empty()
2121+
} else if let Some(ty) = lhs.static_ty.basic_type() {
2122+
if ty.path == "/callee" && name == "proc" {
2123+
// Special cased for now because this might be the only place it appears?
2124+
// Or maybe we should also handle new procpath() returning a procpath.
2125+
Analysis::from(StaticType::Proc)
2126+
} else if let Some(decl) = ty.get_var_declaration(name) {
21032127
if ty != self.ty && decl.var_type.flags.is_private() {
21042128
error(location, format!("field {name:?} on {ty} is declared as private"))
21052129
.with_errortype("private_var")
@@ -2278,6 +2302,9 @@ impl<'o, 's> AnalyzeProc<'o, 's> {
22782302
StaticType::List { list, .. } => {
22792303
typeerror = "list";
22802304
},
2305+
StaticType::Proc => {
2306+
return Analysis::empty()
2307+
}
22812308
};
22822309
error(location, format!("Attempting {operator} on a {typeerror} which does not overload {operator}"))
22832310
.register(self.context);

0 commit comments

Comments
 (0)