Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Structs: Type inference #1910

Open
wants to merge 50 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e339d0c
Structs type inference
gzanitti Oct 15, 2024
9ccca9b
expression_processor
gzanitti Oct 15, 2024
70b8684
missed import
gzanitti Oct 15, 2024
26e35b4
test
gzanitti Oct 15, 2024
d853b76
Comments & tests
gzanitti Oct 16, 2024
8cbc187
let Some(...) -> unwrap()
gzanitti Oct 16, 2024
014553a
var renamed
gzanitti Oct 16, 2024
bb83f5e
instantiate_type_scheme_with_args & test
gzanitti Oct 17, 2024
bb2cfdf
test failing
gzanitti Oct 18, 2024
21673dc
WIP
gzanitti Oct 21, 2024
3224e8f
type_args
gzanitti Oct 21, 2024
c220937
Conflicts
gzanitti Oct 22, 2024
11343fc
Comments and fn renamed
gzanitti Oct 22, 2024
5e0c852
Fix test
gzanitti Oct 23, 2024
385942d
comment to explain desambiguation between typevar y namedtype
gzanitti Oct 23, 2024
0e1108e
comment to explain desambiguation between typevar y namedtype
gzanitti Oct 23, 2024
42159eb
updated
gzanitti Oct 25, 2024
bbf92f6
extra test
gzanitti Oct 25, 2024
b488fc6
updated should_panic
gzanitti Oct 25, 2024
56d1ce4
helper removed
gzanitti Oct 25, 2024
5906b52
wip
gzanitti Oct 28, 2024
4722cfa
Merge remote-tracking branch 'upstream/main' into structs_type_check
gzanitti Oct 29, 2024
eb7bc37
DeclaredType
gzanitti Oct 29, 2024
26004d0
WIP - Goodbye structs_declarations param from typechecker
gzanitti Oct 29, 2024
fb97e31
Not so fast struct_declarations
gzanitti Oct 29, 2024
9687213
still wip
gzanitti Oct 30, 2024
8c81f45
Better inference
gzanitti Oct 30, 2024
e6a3d9f
Merge remote-tracking branch 'upstream/main' into structs_type_check
gzanitti Oct 30, 2024
4990cb5
more tests
gzanitti Oct 30, 2024
181f5da
Merge remote-tracking branch 'upstream/main' into structs_type_check
gzanitti Oct 30, 2024
81439b6
new test & main
gzanitti Oct 30, 2024
5e9b917
shouldnt be failing
gzanitti Oct 30, 2024
12cc596
Better error msg for Structs in asm
gzanitti Oct 31, 2024
c131964
reparse blacklist
gzanitti Oct 31, 2024
2bd3f70
code simplification
gzanitti Oct 31, 2024
dabf58e
code simplification & avoid clone
gzanitti Oct 31, 2024
eebdda6
Update pil-analyzer/src/type_inference.rs
gzanitti Oct 31, 2024
22a7b05
wip
gzanitti Oct 31, 2024
a74c07c
Introduce DeclatedType
gzanitti Oct 31, 2024
611a4fb
Fix introduced bug in verify_type_scheme
gzanitti Nov 1, 2024
84439d8
clippy
gzanitti Nov 1, 2024
93d0507
Update pil-analyzer/src/type_inference.rs
gzanitti Nov 1, 2024
44949c1
Update pil-analyzer/src/type_inference.rs
gzanitti Nov 1, 2024
f56ad9b
new verify_type_schemes + compare_type_schemes
gzanitti Nov 1, 2024
56c2313
Better DeclaredType merged
gzanitti Nov 1, 2024
61fa85b
get names after structs removal
gzanitti Nov 4, 2024
5a62af6
better msg
gzanitti Nov 4, 2024
89eedb1
better msg
gzanitti Nov 4, 2024
2b298f7
names
gzanitti Nov 4, 2024
2a00f32
declared_type
gzanitti Nov 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 3 additions & 9 deletions pil-analyzer/src/expression_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,22 +190,16 @@ impl<'a, D: AnalysisDriver> ExpressionProcessor<'a, D> {
self.process_block_expression(statements, expr, src)
}
PExpression::FreeInput(_, _) => panic!(),
PExpression::StructExpression(
src,
StructExpression {
name: reference,
fields,
},
) => {
let type_args = reference
PExpression::StructExpression(src, StructExpression { name, fields }) => {
let type_args = name
.type_args
.map(|args| args.into_iter().map(|t| self.process_type(t)).collect());

Expression::StructExpression(
src,
StructExpression {
name: Reference::Poly(PolynomialReference {
name: self.driver.resolve_type_ref(&reference.path),
name: self.driver.resolve_type_ref(&name.path),
type_args,
}),
fields: fields
Expand Down
40 changes: 27 additions & 13 deletions pil-analyzer/src/type_inference.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
use std::{
collections::{BTreeSet, HashMap},
str::FromStr,
};
use std::collections::{BTreeSet, HashMap};

use itertools::Itertools;
use powdr_ast::{
analyzed::{Expression, PolynomialReference, Reference},
parsed::{
asm::SymbolPath,
display::format_type_scheme_around_name,
types::{ArrayType, FunctionType, TupleType, Type, TypeBounds, TypeScheme},
visitor::ExpressionVisitable,
Expand Down Expand Up @@ -738,11 +734,33 @@ impl TypeChecker {
result?
}
Expression::StructExpression(sr, StructExpression { name, fields }) => {
let Reference::Poly(PolynomialReference { name, .. }) = name else {
let Reference::Poly(PolynomialReference { name, type_args }) = name else {
gzanitti marked this conversation as resolved.
Show resolved Hide resolved
unreachable!()
};
let struct_decl = self.struct_declarations.get(name).unwrap();

let scheme = TypeScheme {
ty: Type::TypeVar(struct_decl.name.clone()),
vars: struct_decl.type_vars.clone(),
};
let (ty, args) = self.unifier.instantiate_scheme(scheme);
if let Some(requested_type_args) = type_args {
if requested_type_args.len() != args.len() {
return Err(sr.with_error(format!(
"Expected {} type arguments for struct {name}, but got {}: {}",
args.len(),
requested_type_args.len(),
requested_type_args.iter().join(", ")
)));
}
gzanitti marked this conversation as resolved.
Show resolved Hide resolved
for (requested, inferred) in requested_type_args.iter_mut().zip(&args) {
requested.substitute_type_vars(&self.declared_type_vars);
self.unifier
gzanitti marked this conversation as resolved.
Show resolved Hide resolved
.unify_types(requested.clone(), inferred.clone())
.map_err(|err| sr.with_error(err))?;
}
}

let field_types: HashMap<_, _> = fields
chriseth marked this conversation as resolved.
Show resolved Hide resolved
.iter()
.map(|named_expr| {
Expand All @@ -752,15 +770,11 @@ impl TypeChecker {
.collect();

for named_expr in fields.iter_mut() {
if let Some(field_type) = field_types.get(&named_expr.name) {
self.expect_type(field_type, named_expr.body.as_mut())?;
}
let field_type = field_types.get(&named_expr.name).unwrap();
self.expect_type(field_type, named_expr.body.as_mut())?;
}

match SymbolPath::from_str(name) {
Ok(named_type) => Ok(Type::NamedType(named_type, None)),
Err(err) => Err(sr.with_error(err))?,
}?
ty
}
})
}
Expand Down
10 changes: 10 additions & 0 deletions pil-analyzer/tests/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -744,3 +744,13 @@ fn simple_struct() {
";
type_check(input, &[("x", "", "Dot")]);
}

#[test]
fn simple_struct_type_arg() {
let input = "
struct Dot<T> { x: int, y: T }
let f: int -> Dot = |i| Dot{x: 0, y: i};
let x = f(0);
";
type_check(input, &[("x", "", "Dot")]);
gzanitti marked this conversation as resolved.
Show resolved Hide resolved
}