Skip to content

Commit

Permalink
frontend: Switch to index traits
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Nov 12, 2024
1 parent ca62dd2 commit c65a17d
Show file tree
Hide file tree
Showing 12 changed files with 114 additions and 198 deletions.
5 changes: 3 additions & 2 deletions dora-frontend/src/generator/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::sema::{
ClassDefinitionId, ConstDefinitionId, EnumDefinitionId, FieldId, GlobalDefinitionId,
StructDefinitionId, TraitDefinitionId,
};
use crate::stdlib_lookup::lookup_fct;
use crate::sym::ModuleSymTable;
use crate::typeck::find_method_call_candidates;
use crate::{empty_sta, test, ty};
Expand Down Expand Up @@ -3891,7 +3892,7 @@ fn gen_vec_load() {
gen_fct(
"fn f(x: Vec[Int32], idx: Int64): Int32 { x(idx) }",
|sa, code, fct| {
let fct_id = cls_method_by_name(sa, "Vec", "get", false).unwrap();
let fct_id = lookup_fct(sa, "traits::IndexGet for collections::Vec#get");
let expected = vec![
PushRegister(r(0)),
PushRegister(r(1)),
Expand All @@ -3915,7 +3916,7 @@ fn gen_vec_store() {
gen_fct(
"fn f(x: Vec[Int32], idx: Int64, value: Int32) { x(idx) = value; }",
|sa, code, fct| {
let fct_id = cls_method_by_name(sa, "Vec", "set", false).unwrap();
let fct_id = lookup_fct(sa, "traits::IndexSet for collections::Vec#set");
let expected = vec![
PushRegister(r(0)),
PushRegister(r(1)),
Expand Down
4 changes: 2 additions & 2 deletions dora-frontend/src/impldefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,9 +1160,9 @@ mod tests {
#[test]
fn impl_generic_extended_ty() {
ok("
trait Foo[T] { fn get(): T; }
trait Foo[T] { fn getter(): T; }
impl[T] Foo[T] for T {
fn get(): T { self }
fn getter(): T { self }
}
fn f(x: Int64): Foo[Int64] { x as Foo[Int64] }
");
Expand Down
16 changes: 12 additions & 4 deletions dora-frontend/src/stdlib_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ fn internal_struct(
struct_id
}

fn resolve_name(sa: &Sema, name: &str, module_id: ModuleDefinitionId) -> SymbolKind {
pub fn resolve_name(sa: &Sema, name: &str, module_id: ModuleDefinitionId) -> SymbolKind {
let path = name.split("::");
let mut sym = SymbolKind::Module(module_id);

Expand Down Expand Up @@ -897,8 +897,16 @@ fn resolve_int64(sa: &Sema) {

fn resolve_array(sa: &Sema) {
intrinsic_method(sa, "collections::Array#size", Intrinsic::ArrayLen);
intrinsic_method(sa, "collections::Array#get", Intrinsic::ArrayGet);
intrinsic_method(sa, "collections::Array#set", Intrinsic::ArraySet);
intrinsic_method(
sa,
"traits::IndexGet for collections::Array#get",
Intrinsic::ArrayGet,
);
intrinsic_method(
sa,
"traits::IndexSet for collections::Array#set",
Intrinsic::ArraySet,
);

intrinsic_method(
sa,
Expand All @@ -924,7 +932,7 @@ fn intrinsic_method(sa: &Sema, path: &str, intrinsic: Intrinsic) -> FctDefinitio
id
}

fn lookup_fct(sa: &Sema, path: &str) -> FctDefinitionId {
pub fn lookup_fct(sa: &Sema, path: &str) -> FctDefinitionId {
let module_id = sa.stdlib_module_id();

if path.contains("#") {
Expand Down
3 changes: 2 additions & 1 deletion dora-frontend/src/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::sema::{
LazyLambdaCreationData, Sema, TypeParamDefinition,
};
use crate::sym::ModuleSymTable;
use crate::typeck::call::{check_expr_call, create_call_arguments, find_method};
use crate::typeck::call::{check_expr_call, create_call_arguments};
use crate::typeck::constck::ConstCheck;
pub use crate::typeck::control::is_pattern_check;
use crate::typeck::control::{
Expand All @@ -21,6 +21,7 @@ use crate::typeck::function::{
check_args_compatible_fct, check_lit_char, check_lit_float, check_lit_int, check_lit_str,
is_simple_enum, TypeCheck, VarManager,
};
#[cfg(test)]
pub use crate::typeck::lookup::find_method_call_candidates;
use crate::typeck::lookup::MethodLookup;
use crate::typeck::stmt::{check_pattern, check_stmt};
Expand Down
101 changes: 5 additions & 96 deletions dora-frontend/src/typeck/call.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use std::sync::Arc;

use dora_parser::{ast, Span};
use dora_parser::ast;

use crate::access::{
class_accessible_from, class_field_accessible_from, enum_accessible_from, fct_accessible_from,
Expand All @@ -12,13 +12,13 @@ use crate::interner::Name;
use crate::sema::{
find_field_in_class, find_impl, new_identity_type_params, CallType, ClassDefinitionId,
ElementWithFields, EnumDefinitionId, FctDefinitionId, IdentType, Sema, StructDefinitionId,
TraitDefinition, TypeParamDefinition, TypeParamId,
TraitDefinition, TypeParamId,
};
use crate::specialize::replace_type;
use crate::sym::SymbolKind;
use crate::typeck::{
args_compatible, args_compatible_fct, check_args_compatible_fct, check_expr,
find_method_call_candidates, read_path_expr, CallArguments, MethodLookup, TypeCheck,
args_compatible, args_compatible_fct, check_args_compatible_fct, check_expr, read_path_expr,
CallArguments, MethodLookup, TypeCheck,
};
use crate::typeparamck::{self, ErrorReporting};
use crate::{
Expand Down Expand Up @@ -190,7 +190,6 @@ fn check_expr_call_expr(

let trait_id = ck.sa.known.traits.index_get();
let trait_ty = TraitType::from_trait_id(trait_id);
let get = ck.sa.interner.intern("get");

let impl_match = find_impl(
ck.sa,
Expand All @@ -211,7 +210,7 @@ fn check_expr_call_expr(
.get_method_for_trait_method_id(trait_method_id)
.expect("method not found");

let call_type = CallType::Method(expr_type.clone(), method_id, impl_match.bindings.clone());
let call_type = CallType::Expr(expr_type.clone(), method_id, impl_match.bindings.clone());
ck.analysis
.map_calls
.insert_or_replace(e.id, Arc::new(call_type));
Expand All @@ -224,24 +223,6 @@ fn check_expr_call_expr(
ck.analysis.set_ty(e.id, return_type.clone());

return_type
} else if let Some(descriptor) = find_method(
ck,
e.span,
expr_type.clone(),
false,
get,
&arg_types,
&SourceTypeArray::empty(),
) {
let call_type =
CallType::Expr(expr_type.clone(), descriptor.fct_id, descriptor.type_params);
ck.analysis
.map_calls
.insert_or_replace(e.id, Arc::new(call_type));

ck.analysis.set_ty(e.id, descriptor.return_type.clone());

descriptor.return_type
} else {
let ty = ck.ty_name(&expr_type);
ck.sa.report(
Expand Down Expand Up @@ -1230,75 +1211,3 @@ fn check_expr_call_sym(
}
}
}

pub(super) fn find_method(
ck: &mut TypeCheck,
span: Span,
object_type: SourceType,
is_static: bool,
name: Name,
args: &[SourceType],
fct_type_params: &SourceTypeArray,
) -> Option<MethodDescriptor> {
let descriptor = lookup_method(
ck.sa,
object_type.clone(),
ck.type_param_definition,
is_static,
name,
args,
fct_type_params,
);

if descriptor.is_none() {
let type_name = ck.ty_name(&object_type);
let name = ck.sa.interner.str(name).to_string();
let msg = if is_static {
ErrorMessage::UnknownStaticMethod(type_name, name)
} else {
ErrorMessage::UnknownMethod(type_name, name)
};

ck.sa.report(ck.file_id, span, msg);
}

descriptor
}

pub(super) struct MethodDescriptor {
pub fct_id: FctDefinitionId,
pub type_params: SourceTypeArray,
pub return_type: SourceType,
}

pub(super) fn lookup_method(
sa: &Sema,
object_type: SourceType,
type_param_defs: &TypeParamDefinition,
is_static: bool,
name: Name,
args: &[SourceType],
fct_type_params: &SourceTypeArray,
) -> Option<MethodDescriptor> {
let candidates = find_method_call_candidates(sa, object_type, type_param_defs, name, is_static);

if candidates.len() == 1 {
let method_id = candidates[0].fct_id;
let method = sa.fct(method_id);

let container_type_params = &candidates[0].container_type_params;
let type_params = container_type_params.connect(fct_type_params);

if args_compatible_fct(sa, method, args, &type_params, None) {
let cmp_type = replace_type(sa, method.return_type(), Some(&type_params), None);

return Some(MethodDescriptor {
fct_id: method_id,
type_params: type_params,
return_type: cmp_type,
});
}
}

None
}
19 changes: 2 additions & 17 deletions dora-frontend/src/typeck/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::typeck::{
arg_allows, check_args_compatible, check_expr_break_and_continue, check_expr_call,
check_expr_for, check_expr_if, check_expr_match, check_expr_return, check_expr_while,
check_lit_char, check_lit_float, check_lit_int, check_lit_str, check_pattern, check_stmt,
create_call_arguments, find_method, is_simple_enum, TypeCheck,
create_call_arguments, is_simple_enum, TypeCheck,
};
use crate::typeparamck::{self, ErrorReporting};
use crate::{replace_type, ty::error as ty_error, SourceType, SourceTypeArray, SymbolKind};
Expand Down Expand Up @@ -280,8 +280,6 @@ fn check_expr_assign_call(ck: &mut TypeCheck, e: &ast::ExprBinType) {
let value_type = check_expr(ck, &e.rhs, SourceType::Any);
ck.analysis.set_ty(e.rhs.id(), value_type.clone());

let name = ck.sa.interner.intern("set");

let mut arg_types = args.assume_all_positional(ck);
arg_types.push(value_type.clone());

Expand Down Expand Up @@ -317,7 +315,7 @@ fn check_expr_assign_call(ck: &mut TypeCheck, e: &ast::ExprBinType) {
.expect("missing alias");
let impl_item_type_alias = ck.sa.alias(impl_item_type_alias_id);

let call_type = CallType::Method(expr_type.clone(), method_id, impl_match.bindings.clone());
let call_type = CallType::Expr(expr_type.clone(), method_id, impl_match.bindings.clone());
ck.analysis
.map_calls
.insert_or_replace(e.id, Arc::new(call_type));
Expand All @@ -343,19 +341,6 @@ fn check_expr_assign_call(ck: &mut TypeCheck, e: &ast::ExprBinType) {
ErrorMessage::WrongTypeForArgument(exp, got),
);
}
} else if let Some(descriptor) = find_method(
ck,
e.span,
expr_type.clone(),
false,
name,
&arg_types,
&SourceTypeArray::empty(),
) {
let call_type = CallType::Expr(expr_type, descriptor.fct_id, descriptor.type_params);
ck.analysis
.map_calls
.insert_or_replace(e.id, Arc::new(call_type));
} else {
let ty = ck.ty_name(&expr_type);
ck.sa.report(
Expand Down
64 changes: 19 additions & 45 deletions dora-frontend/src/typeck/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -485,16 +485,10 @@ fn type_array_assign() {
);
errors(
"fn f(a: Array[Int32]) { a(3) = \"b\"; }",
&[
(
(1, 25),
ErrorMessage::UnknownMethod("Array[Int32]".into(), "set".into()),
),
(
(1, 25),
ErrorMessage::IndexSetNotImplemented("Array[Int32]".into()),
),
],
&[(
(1, 32),
ErrorMessage::WrongTypeForArgument("Int32".into(), "String".into()),
)],
);
}

Expand Down Expand Up @@ -1340,34 +1334,24 @@ fn test_array_syntax_set() {
#[test]
fn test_array_syntax_set_wrong_value() {
errors(
"fn f(t: Array[Int32]) { t(0) = true; }",
&[
(
(1, 25),
ErrorMessage::UnknownMethod("Array[Int32]".into(), "set".into()),
),
(
(1, 25),
ErrorMessage::IndexSetNotImplemented("Array[Int32]".into()),
),
],
"
fn f(t: Array[Int32]) { t(0) = true; }
",
&[(
(2, 44),
ErrorMessage::WrongTypeForArgument("Int32".into(), "Bool".into()),
)],
);
}

#[test]
fn test_array_syntax_set_wrong_index() {
errors(
"fn f(t: Array[Int32]){ t(\"bla\") = 9i32; }",
&[
(
(1, 24),
ErrorMessage::UnknownMethod("Array[Int32]".into(), "set".into()),
),
(
(1, 24),
ErrorMessage::IndexSetNotImplemented("Array[Int32]".into()),
),
],
&[(
(1, 26),
ErrorMessage::WrongTypeForArgument("Int64".into(), "String".into()),
)],
);
}

Expand Down Expand Up @@ -2707,16 +2691,10 @@ fn shadow_function() {
ok("fn f() { let f = 1i32; }");
errors(
"fn f() { let f = 1i32; f(); }",
&[
(
(1, 24),
ErrorMessage::UnknownMethod("Int32".into(), "get".into()),
),
(
(1, 24),
ErrorMessage::IndexGetNotImplemented("Int32".into()),
),
],
&[(
(1, 24),
ErrorMessage::IndexGetNotImplemented("Int32".into()),
)],
);
}

Expand Down Expand Up @@ -3478,10 +3456,6 @@ fn different_fct_call_kinds() {
"fn f() { 1i32[Int32](); }",
&[
((1, 10), ErrorMessage::NoTypeParamsExpected),
(
(1, 10),
ErrorMessage::UnknownMethod("Int32".into(), "get".into()),
),
(
(1, 10),
ErrorMessage::IndexGetNotImplemented("Int32".into()),
Expand Down
10 changes: 8 additions & 2 deletions dora-runtime/src/stdlib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,8 +619,14 @@ pub const STDLIB_FUNCTIONS: &[(&'static str, FctImplementation)] = &[
("stdlib::string::String#getByte", I(Intrinsic::StrGet)),
// Array
("stdlib::collections::Array#size", I(Intrinsic::ArrayLen)),
("stdlib::collections::Array#get", I(Intrinsic::ArrayGet)),
("stdlib::collections::Array#set", I(Intrinsic::ArraySet)),
(
"stdlib::traits::IndexGet for stdlib::collections::Array#get",
I(Intrinsic::ArrayGet),
),
(
"stdlib::traits::IndexSet for stdlib::collections::Array#set",
I(Intrinsic::ArraySet),
),
(
"stdlib::collections::Array#unsafeNew",
I(Intrinsic::ArrayNewOfSize),
Expand Down
Loading

0 comments on commit c65a17d

Please sign in to comment.