Skip to content

Commit

Permalink
fix: type inference tweaks
Browse files Browse the repository at this point in the history
  • Loading branch information
jac3km4 committed Nov 5, 2023
1 parent 8431f2f commit 6cc0835
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 27 deletions.
2 changes: 1 addition & 1 deletion compiler/src/type_repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ impl<'repo, 'id> Iterator for UpperIter<'repo, 'id> {

fn next(&mut self) -> Option<Self::Item> {
let id = self.current?;
let class = self.db[id].as_class().expect("base type should be a class");
let class = self.db[id].as_class()?;
self.current = class.extends.as_ref().map(|typ| typ.id);
Some((id, class))
}
Expand Down
26 changes: 9 additions & 17 deletions compiler/src/typer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,7 @@ impl<'ctx, 'id> Typer<'ctx, 'id> {
}
let (expr, expr_ty) = self.typeck(expr, locals)?;
let upper_bound = expr_ty
.known_upper_bound(self.repo)
.force_upper_bound(self.repo)
.ok_or(CompileError::CannotLookupMember(*span))?;
let (id, fty) = self
.repo
Expand Down Expand Up @@ -518,7 +518,7 @@ impl<'ctx, 'id> Typer<'ctx, 'id> {
(
Some(expr),
expr_type
.known_upper_bound(self.repo)
.force_upper_bound(self.repo)
.ok_or(CompileError::CannotLookupMember(span))?,
Some(expr_type),
)
Expand Down Expand Up @@ -1054,20 +1054,16 @@ impl<'id> InferType<'id> {
}
}

fn known_upper_bound(&self, type_repo: &TypeRepo<'id>) -> Option<Data<'id>> {
fn force_upper_bound(&self, type_repo: &TypeRepo<'id>) -> Option<Data<'id>> {
if let Some((_, typ)) = self.ref_type() {
typ.known_upper_bound(type_repo)
typ.force_upper_bound(type_repo)
} else {
match self {
Self::Mono(mono) => mono.known_upper_bound(),
Self::Poly(var) => {
let lower = var.borrow().only_lower_bounded();
if let Some(lower) = lower {
Var::add_upper_bound(var.clone(), &lower, type_repo).ok()?;
lower.known_upper_bound()
} else {
var.borrow().upper.known_upper_bound()
}
let bound = Var::either_bound(var.clone())?;
Var::add_upper_bound(var.clone(), &bound, type_repo).ok()?;
bound.known_upper_bound()
}
}
}
Expand Down Expand Up @@ -1130,7 +1126,7 @@ impl<'id> Mono<'id> {
}
}
(&Self::Prim(n0), &Self::Prim(n1)) if n0 == n1 => Ok(Self::Prim(n0)),
(Self::Data(_), Self::Prim(prim)) => {
(Self::Data(data), Self::Prim(prim)) if !type_repo[data.id].is_builtin() => {
let id = prim
.boxed_type()
.ok_or_else(|| TypeError::CannotUnify(self.clone(), rhs.clone()))?;
Expand Down Expand Up @@ -1200,7 +1196,7 @@ impl<'id> Mono<'id> {
(Self::Var(lhs), Self::Var(rhs)) if lhs.name == rhs.name => Ok(()),
(Self::Var(lhs), rhs) if lhs.upper != Mono::Top => lhs.upper.constrain(rhs, type_repo),
(lhs, Self::Var(rhs)) if rhs.lower != Mono::Bottom => lhs.constrain(&rhs.upper, type_repo),
(Self::Prim(prim), Self::Data(_)) => {
(Self::Prim(prim), Self::Data(data)) if !type_repo[data.id].is_builtin() => {
let id = prim
.boxed_type()
.ok_or_else(|| TypeError::Mismatch(self.clone(), rhs.clone()))?;
Expand Down Expand Up @@ -1383,10 +1379,6 @@ impl<'id> Var<'id> {
Ok(())
}

fn only_lower_bounded(&self) -> Option<Mono<'id>> {
(self.upper.is_top() && !self.lower.is_bottom()).then(|| self.lower.clone())
}

pub(crate) fn either_bound(this: RcVar<'id>) -> Option<Mono<'id>> {
let rep = Self::rep(this);
let rep = rep.borrow();
Expand Down
16 changes: 8 additions & 8 deletions lib/Predef.reds
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ import Std.{Primitive, Primitive}
// intrinsics
public func Equals<A>(lhs: A, rhs: A) -> Bool;
public func NotEquals<A>(lhs: A, rhs: A) -> Bool;
public func ArrayClear<A>(out array: array<A>);
public func ArrayClear<A>(array: array<A>);
public func ArraySize<A>(array: array<A>) -> Int32;
public func ArrayResize<A>(out array: array<A>, size: Int32);
public func ArrayResize<A>(array: array<A>, size: Int32);
public func ArrayFindFirst<A>(array: array<A>, needle: A) -> A;
public func ArrayFindLast<A>(array: array<A>, needle: A) -> A;
public func ArrayContains<A>(array: array<A>, needle: A) -> Bool;
public func ArrayCount<A>(array: array<A>, needle: A) -> Int32;
public func ArrayPush<A>(out array: array<A>, elem: A);
public func ArrayPop<A>(out array: array<A>) -> A;
public func ArrayInsert<A>(out array: array<A>, idx: Int32, elem: A);
public func ArrayRemove<A>(out array: array<A>, elem: A);
public func ArrayGrow<A>(out array: array<A>, size: Int32);
public func ArrayErase<A>(out array: array<A>, idx: Int32) -> Bool;
public func ArrayPush<A>(array: array<A>, elem: A);
public func ArrayPop<A>(array: array<A>) -> A;
public func ArrayInsert<A>(array: array<A>, idx: Int32, elem: A);
public func ArrayRemove<A>(array: array<A>, elem: A);
public func ArrayGrow<A>(array: array<A>, size: Int32);
public func ArrayErase<A>(array: array<A>, idx: Int32) -> Bool;
public func ArrayLast<A>(array: array<A>) -> A;

public func ToString<A>(a: A) -> String;
Expand Down
2 changes: 1 addition & 1 deletion lib/Std/Iter.reds
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public abstract class Iter<A> {
return state;
}

public final func Into<C extends Extendable<A>>(out sink: C) -> C {
public final func Into<C extends Extendable<A>>(sink: C) -> C {
while this.HasNext() {
sink.Extend(this.Next());
}
Expand Down

0 comments on commit 6cc0835

Please sign in to comment.