Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into upgrade-llvm
Browse files Browse the repository at this point in the history
  • Loading branch information
yhara committed Aug 10, 2023
2 parents 106ab49 + 1d2f739 commit 7c5e8f4
Show file tree
Hide file tree
Showing 12 changed files with 303 additions and 278 deletions.
440 changes: 227 additions & 213 deletions Cargo.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ env_logger = "0.8.2"
log = "0.4.11"
serde = { version = "1.0.125", features = ["derive"] }
serde_json = "1.0"
mac-sys-info = { version = "0.1.13", optional = true }
os_info = "3.7.0"

chrono = "0.4"
chrono-tz = "0.8"
6 changes: 3 additions & 3 deletions builtin/array.sk
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ class Array<T> : Enumerable<T>
if self.empty?
None
else
Some<T>.new(self[0])
Some.new(self[0])
end
end

Expand Down Expand Up @@ -136,7 +136,7 @@ class Array<T> : Enumerable<T>
if empty?
None
else
Some<T>.new(self[length - 1])
Some.new(self[length - 1])
end
end

Expand Down Expand Up @@ -262,6 +262,6 @@ class Array<T> : Enumerable<T>
a.push(self[i])
end
end
Pair<Array<T>, Array<T>>.new(a, b)
Pair.new(a, b)
end
end
4 changes: 2 additions & 2 deletions builtin/dict.sk
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class Dict<K, V> : Enumerable<Pair<K, V>>
end
end
unless done
@pairs.push(Pair<KK, VV>.new(key, value))
@pairs.push(Pair.new(key, value))
end
end

Expand All @@ -28,7 +28,7 @@ class Dict<K, V> : Enumerable<Pair<K, V>>
var ret = None
@pairs.each do |pair|
if pair.fst == key
ret = Some<VV>.new(pair.snd)
ret = Some.new(pair.snd)
end
end
ret
Expand Down
4 changes: 2 additions & 2 deletions builtin/enumerable.sk
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ module Enumerable<E>
match [a.length, b.length].min
when Maybe::Some(n)
0.upto(n-1) do |i|
ret.push(Pair<A, B>.new(a[i], b[i]))
ret.push(Pair.new(a[i], b[i]))
end
end
ret
Expand Down Expand Up @@ -37,7 +37,7 @@ module Enumerable<E>

# Like `map` but `f` should return an array and the result is flattened.
def flat_map<R>(f: Fn1<E, Array<R>>) -> Array<R>
self.map<Array<R>>(f).fold<Array<R>>(Array<R>.new){|sum: Array<R>, item: Array<R>|
self.map(f).fold(Array<R>.new){|sum: Array<R>, item: Array<R>|
sum.append(item)
sum
}
Expand Down
2 changes: 1 addition & 1 deletion builtin/file.sk
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class File : Readable
when Ok(file)
let v = f(file)
#file.close
Ok<V>.new(v)
Ok.new(v)
when Fail(e)
Fail<V>.new(e)
end
Expand Down
2 changes: 1 addition & 1 deletion builtin/maybe.sk
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ enum Maybe<V>
def map<U>(f: Fn1<V, U>) -> Maybe<U>
match self
when Some(v)
Some<U>.new(f(v))
Some.new(f(v))
else
None
end
Expand Down
4 changes: 2 additions & 2 deletions builtin/readable.sk
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ module Readable
return Fail<Array<String>>.new(e)
end
end
Ok<Array<String>>.new(a)
Ok.new(a)
end

def read -> Result<String>
Expand All @@ -65,6 +65,6 @@ module Readable
return Fail<String>.new(e)
end
end
Ok<String>.new(acc._unsafe_to_s)
Ok.new(acc._unsafe_to_s)
end
end
50 changes: 37 additions & 13 deletions lib/skc_ast2hir/src/convert_exprs/method_call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,13 @@ pub fn build(
method_tyargs: Vec<TermTy>,
locs: &LocationSpan,
) -> Result<HirExpression> {
check_argument_types(mk, &found.sig, &receiver_hir, &mut arg_hirs, &inf)?;
let receiver_ty = receiver_hir.ty.clone();
let specialized = receiver_hir.ty.is_specialized();
let first_arg_ty = arg_hirs.get(0).map(|x| x.ty.clone());
let arg_types = arg_hirs.iter().map(|x| x.ty.clone()).collect::<Vec<_>>();
let infer_tyargs = found.sig.has_typarams() && method_tyargs.is_empty();

let receiver = Hir::bit_cast(found.owner.to_term_ty(), receiver_hir);
let args = if specialized {
arg_hirs
.into_iter()
.map(|expr| Hir::bit_cast(ty::raw("Object"), expr))
.collect::<Vec<_>>()
} else {
arg_hirs
};
let tyargs = if method_tyargs.is_empty() {
let tyargs = if infer_tyargs {
let err = error::method_tyarg_inference_failed(
format!("Could not infer type arg(s) of {}", found.sig),
locs,
Expand All @@ -267,12 +258,45 @@ pub fn build(
method_tyargs
};

let updated_param_types = if infer_tyargs {
found
.sig
.params
.iter()
.map(|param| param.ty.substitute(Default::default(), &tyargs))
.collect::<Vec<_>>()
} else {
found
.sig
.params
.iter()
.map(|param| param.ty.clone())
.collect::<Vec<_>>()
};
check_argument_types(
mk,
&found.sig,
&receiver_hir,
&mut arg_hirs,
&updated_param_types,
)?;

let args = if specialized {
arg_hirs
.into_iter()
.map(|expr| Hir::bit_cast(ty::raw("Object"), expr))
.collect::<Vec<_>>()
} else {
arg_hirs
};

// Special handling for `Foo.new(x)` where `Foo<T>` is a generic class and
// `T` is inferred from `x`.
if found.is_generic_new(&receiver_ty) {
return Ok(call_specialized_new(mk, &receiver_ty, args, tyargs, locs));
}

let receiver = Hir::bit_cast(found.owner.to_term_ty(), receiver_hir);
let hir = build_hir(mk, &found, receiver, args, tyargs, &inf);
if found.sig.fullname.full_name == "Object#unsafe_cast" {
Ok(Hir::bit_cast(first_arg_ty.unwrap().instance_ty(), hir))
Expand All @@ -286,9 +310,9 @@ fn check_argument_types(
sig: &MethodSignature,
receiver_hir: &HirExpression,
arg_hirs: &mut [HirExpression],
inf: &Option<method_call_inf::MethodCallInf3>,
arg_types: &[TermTy],
) -> Result<()> {
type_checking::check_method_args(&mk.class_dict, sig, receiver_hir, arg_hirs, inf)?;
type_checking::check_method_args(&mk.class_dict, sig, receiver_hir, arg_hirs, arg_types)?;
if let Some(last_arg) = arg_hirs.last_mut() {
check_break_in_block(sig, last_arg)?;
}
Expand Down
36 changes: 12 additions & 24 deletions lib/skc_ast2hir/src/type_system/type_checking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ pub fn check_method_args(
sig: &MethodSignature,
_receiver_hir: &HirExpression,
arg_hirs: &[HirExpression],
inf: &Option<method_call_inf::MethodCallInf3>,
param_types: &[TermTy],
) -> Result<()> {
let mut result = check_method_arity(sig, arg_hirs);
if result.is_ok() {
result = check_arg_types(class_dict, sig, arg_hirs, inf);
result = check_arg_types(class_dict, sig, arg_hirs, param_types);
}

if result.is_err() {
Expand Down Expand Up @@ -152,13 +152,13 @@ fn check_arg_types(
class_dict: &ClassDict,
sig: &MethodSignature,
arg_hirs: &[HirExpression],
inf: &Option<method_call_inf::MethodCallInf3>,
param_types: &[TermTy],
) -> Result<()> {
for i in 0..sig.params.len() {
let param = &sig.params[i];
let arg_hir = &arg_hirs[i];
let inferred = inf.as_ref().map(|x| &x.solved_method_arg_tys[i]);
check_arg_type(class_dict, sig, arg_hir, param, &inferred)?;
let param_ty = &param_types[i];
check_arg_type(class_dict, sig, arg_hir, param, param_ty)?;
}
Ok(())
}
Expand All @@ -169,32 +169,20 @@ fn check_arg_type(
sig: &MethodSignature,
arg_hir: &HirExpression,
param: &MethodParam,
inferred: &Option<&TermTy>,
param_ty: &TermTy,
) -> Result<()> {
if inferred.is_some() {
// Type inferrence succeed == no type error found
return Ok(());
}
let expected = &param.ty;
let arg_ty = &arg_hir.ty;
if class_dict.conforms(arg_ty, expected) {
if class_dict.conforms(arg_ty, param_ty) {
return Ok(());
}

let msg = if inferred.is_some() {
format!(
"the argument `{}' of `{}' is inferred to {} but got {}",
param.name, sig.fullname, expected, arg_ty.fullname
)
} else {
format!(
"the argument `{}' of `{}' should be {} but got {}",
param.name, sig.fullname, param.ty, arg_ty
)
};
let msg = format!(
"the argument `{}' of `{}' should be {} but got {}",
param.name, sig.fullname, param_ty, arg_ty
);
let locs = &arg_hir.locs;
let report = skc_error::build_report(msg, locs, |r, locs_span| {
r.with_label(Label::new(locs_span).with_message(&arg_hir.ty))
r.with_label(Label::new(locs_span).with_message(&arg_ty))
});
Err(type_error(report))
}
Expand Down
4 changes: 4 additions & 0 deletions lib/skc_hir/src/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ impl MethodSignature {
self.params.iter().any(|p| p.has_default)
}

pub fn has_typarams(&self) -> bool {
!self.typarams.is_empty()
}

pub fn is_class_method(&self) -> bool {
self.fullname.type_name.is_meta()
}
Expand Down
27 changes: 11 additions & 16 deletions src/targets.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
use os_info::{Type, Version};

/// Returns default `TargetTriple`
#[cfg(feature = "mac")]
pub fn default_triple() -> inkwell::targets::TargetTriple {
if let Ok(info) = mac_sys_info::get_mac_sys_info() {
// #281: get_default_triple returns `darwin` but clang shows warning for it
let arch = info.cpu_info().architecture();
let ver = info.os_info().os_version();
// #281: Add .0
let n_dots = ver.chars().filter(|c| *c == '.').count();
let zero = if n_dots >= 2 { "" } else { ".0" };
let s = format!("{}-apple-macosx{}{}", arch, ver, zero);
inkwell::targets::TargetTriple::create(&s)
} else {
inkwell::targets::TargetMachine::get_default_triple()
let info = os_info::get();
if info.os_type() == Type::Macos {
// #281: calculate target triple to avoid clang's warning
if let Some(arch) = info.architecture() {
if let Version::Semantic(major, minor, patch) = info.version() {
let s = format!("{}-apple-macosx{}.{}.{}", arch, major, minor, patch);
return inkwell::targets::TargetTriple::create(&s);
}
}
}
}

#[cfg(not(feature = "mac"))]
pub fn default_triple() -> inkwell::targets::TargetTriple {
inkwell::targets::TargetMachine::get_default_triple()
}

0 comments on commit 7c5e8f4

Please sign in to comment.