Skip to content

Commit

Permalink
Fix method type checking, remove redundant type annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
osa1 committed Feb 2, 2025
1 parent 5707436 commit 33f6b4b
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 59 deletions.
3 changes: 2 additions & 1 deletion lib/Prelude.fir
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ prim Array.set(self: Array[t], idx: U32, elem: t)

impl[ToStr[t]] ToStr[Array[t]]:
toStr(self: Array[t]): Str
let buf = StrBuf.withCapacity(self.len() * 5u32 + 2u32)
let buf = StrBuf.withCapacity(self.len() * 5 + 2)
buf.push('[')
for i in range(0u32, self.len()):
let i: U32 = i
if i != 0:
buf.push(',')
buf.pushStr(self.get(i).toStr())
Expand Down
24 changes: 12 additions & 12 deletions lib/Str.fir
Original file line number Diff line number Diff line change
Expand Up @@ -63,20 +63,20 @@ Str.charAt(self, byteIndex: U32): Char
if byte & 0b1110_0000 == 0b1100_0000:
# 2 bytes
let b0 = (byte & 0b11111).asU32()
let b1 = (self._bytes.get(byteIndex + 1u32) & 0b111111).asU32()
let b1 = (self._bytes.get(byteIndex + 1) & 0b111111).asU32()
Char(_codePoint = (b0 << 6) | b1)
elif byte & 0b1111_0000 == 0b1110_0000:
# 3 bytes
let b0 = (byte & 0b1111).asU32()
let b1 = (self._bytes.get(byteIndex + 1u32) & 0b111111).asU32()
let b2 = (self._bytes.get(byteIndex + 2u32) & 0b111111).asU32()
let b1 = (self._bytes.get(byteIndex + 1) & 0b111111).asU32()
let b2 = (self._bytes.get(byteIndex + 2) & 0b111111).asU32()
Char(_codePoint = (b0 << 12) | (b1 << 6) | b2)
else:
# 4 bytes
let b0 = (byte & 0b111).asU32()
let b1 = (self._bytes.get(byteIndex + 1u32) & 0b111111).asU32()
let b2 = (self._bytes.get(byteIndex + 2u32) & 0b111111).asU32()
let b3 = (self._bytes.get(byteIndex + 3u32) & 0b111111).asU32()
let b1 = (self._bytes.get(byteIndex + 1) & 0b111111).asU32()
let b2 = (self._bytes.get(byteIndex + 2) & 0b111111).asU32()
let b3 = (self._bytes.get(byteIndex + 3) & 0b111111).asU32()
Char(_codePoint = (b0 << 18) | (b1 << 12) | (b2 << 6) | b3)

Str.chars(self): CharIter
Expand Down Expand Up @@ -165,20 +165,20 @@ _charAt(bytes: Array[U8], idx: U32): Char
if byte & 0b1110_0000 == 0b1100_0000:
# 2 bytes
let b0 = (byte & 0b11111).asU32()
let b1 = (bytes.get(idx + 1u32) & 0b111111).asU32()
let b1 = (bytes.get(idx + 1) & 0b111111).asU32()
Char(_codePoint = (b0 << 6) | b1)
elif byte & 0b1111_0000 == 0b1110_0000:
# 3 bytes
let b0 = (byte & 0b1111).asU32()
let b1 = (bytes.get(idx + 1u32) & 0b111111).asU32()
let b2 = (bytes.get(idx + 2u32) & 0b111111).asU32()
let b1 = (bytes.get(idx + 1) & 0b111111).asU32()
let b2 = (bytes.get(idx + 2) & 0b111111).asU32()
Char(_codePoint = (b0 << 12) | (b1 << 6) | b2)
else:
# 4 bytes
let b0 = (byte & 0b111).asU32()
let b1 = (bytes.get(idx + 1u32) & 0b111111).asU32()
let b2 = (bytes.get(idx + 2u32) & 0b111111).asU32()
let b3 = (bytes.get(idx + 3u32) & 0b111111).asU32()
let b1 = (bytes.get(idx + 1) & 0b111111).asU32()
let b2 = (bytes.get(idx + 2) & 0b111111).asU32()
let b3 = (bytes.get(idx + 3) & 0b111111).asU32()
Char(_codePoint = (b0 << 18) | (b1 << 12) | (b2 << 6) | b3)

type SplitWhitespace:
Expand Down
13 changes: 7 additions & 6 deletions lib/Vec.fir
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Vec.push(self: Vec[t], elem: t)
let cap = self._data.len()

if self._len == cap:
let newData = Array.new(cap * 2u32)
let newData = Array.new(cap * 2)
for i in range(0u32, cap):
newData.set(i, self._data.get(i))
self._data = newData
Expand Down Expand Up @@ -71,7 +71,7 @@ Vec.iter(self: Vec[t]): VecIter[t]

Vec.sort[Ord[t]](self: Vec[t])
if self.len() != 0:
_quicksort(self, 0, self.len() - 1u32)
_quicksort(self, 0, self.len() - 1)

_quicksort[Ord[t]](vec: Vec[t], low: U32, high: U32)
if low >= high:
Expand All @@ -80,15 +80,15 @@ _quicksort[Ord[t]](vec: Vec[t], low: U32, high: U32)
let p = _partition(vec, low, high)

if p != low:
_quicksort(vec, low, p - 1u32)
_quicksort(vec, low, p - 1)

_quicksort(vec, p + 1u32, high)
_quicksort(vec, p + 1, high)

_partition[Ord[t]](vec: Vec[t], low: U32, high: U32): U32
let pivot = vec.get(high)
let i = low

for j in irange(low, high - 1u32):
for j in irange(low, high - 1):
if vec.get(j) <= pivot:
vec.swap(i, j)
i += 1
Expand All @@ -98,9 +98,10 @@ _partition[Ord[t]](vec: Vec[t], low: U32, high: U32): U32

impl[ToStr[t]] ToStr[Vec[t]]:
toStr(self: Vec[t]): Str
let buf = StrBuf.withCapacity(self.len() * 5u32 + 2u32)
let buf = StrBuf.withCapacity(self.len() * 5 + 2)
buf.push('[')
for i in range(0u32, self.len()):
let i: U32 = i
if i != 0:
buf.push(',')
buf.pushStr(self.get(i).toStr())
Expand Down
87 changes: 47 additions & 40 deletions src/type_checker/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -939,51 +939,58 @@ fn check_field_select(
_ => {}
}

match select_method(tc_state, object_ty, field, loc, level) {
Some(scheme) => {
let (method_ty, method_ty_args) =
scheme.instantiate(level, tc_state.var_gen, tc_state.preds, loc);

// Type arguments of the receiver already substituted for type parameters in
// `select_method`. Drop 'self' argument.
match method_ty {
let scheme = select_method(tc_state, object_ty, field, loc, level).unwrap_or_else(|| {
panic!(
"{}: Type {} does not have field or method {}",
loc_display(loc),
object_ty,
field
)
});

let (method_ty, method_ty_args) =
scheme.instantiate(level, tc_state.var_gen, tc_state.preds, loc);

// Type arguments of the receiver already substituted for type parameters in
// `select_method`. Drop 'self' argument.
match method_ty {
Ty::Fun {
mut args,
ret,
exceptions,
} => {
match &mut args {
FunArgs::Positional(args) => {
let self_arg = args.remove(0);
unify(
&self_arg,
object_ty,
tc_state.tys.tys.cons(),
&mut tc_state.var_gen,
level,
loc,
);
}
FunArgs::Named(_) => panic!(),
}
(
Ty::Fun {
mut args,
args,
ret,
exceptions,
} => {
match &mut args {
FunArgs::Positional(args) => {
args.remove(0);
}
FunArgs::Named(_) => panic!(),
}
(
Ty::Fun {
args,
ret,
exceptions,
},
ast::Expr::MethodSelect(ast::MethodSelectExpr {
object: Box::new(object.clone()),
object_ty: Some(object_ty.clone()),
method: field.clone(),
ty_args: method_ty_args.into_iter().map(Ty::Var).collect(),
}),
)
}
_ => panic!(
"{}: Type of method is not a function type: {:?}",
loc_display(loc),
method_ty
),
}
},
ast::Expr::MethodSelect(ast::MethodSelectExpr {
object: Box::new(object.clone()),
object_ty: Some(object_ty.clone()),
method: field.clone(),
ty_args: method_ty_args.into_iter().map(Ty::Var).collect(),
}),
)
}
None => panic!(
"{}: Type {} does not have field or method {}",
_ => panic!(
"{}: Type of method is not a function type: {:?}",
loc_display(loc),
object_ty,
field
method_ty
),
}
}
Expand Down

0 comments on commit 33f6b4b

Please sign in to comment.