Skip to content

Commit

Permalink
frontend: Clean up function calls a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Nov 15, 2024
1 parent 8e181d7 commit 7e068cb
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 163 deletions.
129 changes: 69 additions & 60 deletions dora-frontend/src/typeck/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ use crate::typeck::{
args_compatible, args_compatible_fct, check_args_compatible_fct, check_expr, read_path_expr,
CallArguments, MethodLookup, TypeCheck,
};
use crate::typeparamck::{self, ErrorReporting};
use crate::typeparamck;
use crate::{
empty_sta, specialize_type, ty::error as ty_error, ErrorMessage, SourceType, SourceTypeArray,
TraitType,
};

use super::lookup::find_method_call_candidates;

pub(super) fn check_expr_call(
ck: &mut TypeCheck,
e: &ast::ExprCallType,
Expand Down Expand Up @@ -374,61 +376,60 @@ fn check_expr_call_method(

let interned_method_name = ck.sa.interner.intern(&method_name);

let lookup = MethodLookup::new(ck.sa, ck.file_id, ck.type_param_definition)
.no_error_reporting()
.parent(ck.parent.clone())
.method(object_type.clone())
.name(interned_method_name)
.fct_type_params(&fct_type_params)
.args(&arg_types)
.find();

if lookup.find() {
let fct_id = lookup.found_fct_id().unwrap();
let fct = ck.sa.fct(fct_id);
let return_type = lookup.found_ret().unwrap();

let call_type = if object_type.is_self() {
CallType::TraitObjectMethod(object_type, fct_id)
} else if object_type.is_trait() && fct.parent.is_trait() {
CallType::TraitObjectMethod(object_type, fct_id)
} else {
let method_type = lookup.found_class_type().unwrap();
let container_type_params = lookup.found_container_type_params().clone().unwrap();
let type_params = container_type_params.connect(&fct_type_params);
CallType::Method(method_type, fct_id, type_params)
};

ck.analysis
.map_calls
.insert_or_replace(e.id, Arc::new(call_type));
ck.analysis.set_ty(e.id, return_type.clone());

if !method_accessible_from(ck.sa, fct_id, ck.module_id) {
let msg = ErrorMessage::NotAccessible;
ck.sa.report(ck.file_id, e.span, msg);
}
let candidates = find_method_call_candidates(
ck.sa,
object_type.clone(),
&ck.type_param_definition,
interned_method_name,
false,
);

return_type
} else if lookup.found_fct_id().is_none() {
if candidates.is_empty() {
// No method with this name found, so this might actually be a field
check_expr_call_field(ck, e, object_type, method_name, fct_type_params, arguments)
} else {
// Lookup the method again, but this time with error reporting
let lookup = MethodLookup::new(ck.sa, ck.file_id, ck.type_param_definition)
.parent(ck.parent.clone())
.method(object_type)
.method(object_type.clone())
.name(interned_method_name)
.fct_type_params(&fct_type_params)
.span(e.span)
.args(&arg_types)
.find();

assert!(!lookup.find());
if lookup.find() {
let fct_id = lookup.found_fct_id().unwrap();
let fct = ck.sa.fct(fct_id);
let return_type = lookup.found_ret().unwrap();

ck.analysis.set_ty(e.id, ty_error());
let call_type = if object_type.is_self() {
CallType::TraitObjectMethod(object_type, fct_id)
} else if object_type.is_trait() && fct.parent.is_trait() {
CallType::TraitObjectMethod(object_type, fct_id)
} else {
let method_type = lookup.found_class_type().unwrap();
let container_type_params = lookup.found_container_type_params().clone().unwrap();
let type_params = container_type_params.connect(&fct_type_params);
CallType::Method(method_type, fct_id, type_params)
};

ty_error()
ck.analysis
.map_calls
.insert_or_replace(e.id, Arc::new(call_type));
ck.analysis.set_ty(e.id, return_type.clone());

if !method_accessible_from(ck.sa, fct_id, ck.module_id) {
let msg = ErrorMessage::NotAccessible;
ck.sa.report(ck.file_id, e.span, msg);
}

return_type
} else {
ck.analysis.set_ty(e.id, ty_error());

ty_error()
}
}
}

Expand Down Expand Up @@ -522,12 +523,13 @@ fn check_expr_call_struct(
}

let ty = SourceType::Struct(struct_id, type_params.clone());
let type_params_ok = typeparamck::check_struct(
let type_params_ok = typeparamck::check(
ck.sa,
ck.type_param_definition,
struct_id,
struct_,
&type_params,
ErrorReporting::Yes(ck.file_id, e.span),
ck.file_id,
e.span,
);

if !type_params_ok {
Expand Down Expand Up @@ -690,17 +692,19 @@ fn check_expr_call_class(
type_params
};

if !typeparamck::check_class(
let cls = ck.sa.class(cls_id);

if !typeparamck::check(
ck.sa,
ck.type_param_definition,
cls_id,
cls,
&type_params,
ErrorReporting::Yes(ck.file_id, e.span),
ck.file_id,
e.span,
) {
return ty_error();
};

let cls = ck.sa.class(cls_id);
let cls_ty = SourceType::Class(cls_id, type_params.clone());

if !is_default_accessible(ck.sa, cls.module_id, ck.module_id)
Expand Down Expand Up @@ -748,12 +752,13 @@ pub(super) fn check_expr_call_enum_variant(
type_params
};

let type_params_ok = typeparamck::check_enum(
let type_params_ok = typeparamck::check(
ck.sa,
ck.type_param_definition,
enum_id,
enum_,
&type_params,
ErrorReporting::Yes(ck.file_id, e.span),
ck.file_id,
e.span,
);

if !type_params_ok {
Expand Down Expand Up @@ -1020,12 +1025,14 @@ fn check_expr_call_path(

match sym {
Some(SymbolKind::Class(cls_id)) => {
if typeparamck::check_class(
let cls = ck.sa.class(cls_id);
if typeparamck::check(
ck.sa,
ck.type_param_definition,
cls_id,
cls,
&container_type_params,
ErrorReporting::Yes(ck.file_id, e.span),
ck.file_id,
e.span,
) {
let arg_types = arguments.assume_all_positional(ck);
check_expr_call_static_method(
Expand All @@ -1044,12 +1051,13 @@ fn check_expr_call_path(
Some(SymbolKind::Struct(struct_id)) => {
let struct_ = ck.sa.struct_(struct_id);

if typeparamck::check_struct(
if typeparamck::check(
ck.sa,
ck.type_param_definition,
struct_id,
struct_,
&container_type_params,
ErrorReporting::Yes(ck.file_id, e.span),
ck.file_id,
e.span,
) {
let object_ty = if let Some(ref primitive_ty) = struct_.primitive_ty {
assert!(container_type_params.is_empty());
Expand Down Expand Up @@ -1097,12 +1105,13 @@ fn check_expr_call_path(
arguments,
)
} else {
if typeparamck::check_enum(
if typeparamck::check(
ck.sa,
ck.type_param_definition,
enum_id,
enum_,
&container_type_params,
ErrorReporting::Yes(ck.file_id, e.span),
ck.file_id,
e.span,
) {
let object_ty = SourceType::Enum(enum_id, container_type_params);
let arg_types = arguments.assume_all_positional(ck);
Expand Down
16 changes: 9 additions & 7 deletions dora-frontend/src/typeck/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use crate::typeck::{
check_lit_char, check_lit_float, check_lit_int, check_lit_str, check_pattern, check_stmt,
create_call_arguments, is_simple_enum, TypeCheck,
};
use crate::typeparamck::{self, ErrorReporting};
use crate::typeparamck;
use crate::{replace_type, ty::error as ty_error, SourceType, SourceTypeArray, SymbolKind};

pub(super) fn check_expr(
Expand Down Expand Up @@ -1716,12 +1716,13 @@ fn check_enum_variant_without_args(
ck.sa.report(ck.file_id, expr_span, msg);
}

let type_params_ok = typeparamck::check_enum(
let type_params_ok = typeparamck::check(
ck.sa,
ck.type_param_definition,
enum_id,
enum_,
&type_params,
ErrorReporting::Yes(ck.file_id, expr_span),
ck.file_id,
expr_span,
);

let interned_name = ck.sa.interner.intern(&name);
Expand Down Expand Up @@ -1861,12 +1862,13 @@ pub(super) fn check_enum_variant_without_args_id(
type_params
};

let type_params_ok = typeparamck::check_enum(
let type_params_ok = typeparamck::check(
ck.sa,
ck.type_param_definition,
enum_id,
enum_,
&type_params,
ErrorReporting::Yes(ck.file_id, expr_span),
ck.file_id,
expr_span,
);

let variant = &enum_.variants()[variant_idx as usize];
Expand Down
32 changes: 10 additions & 22 deletions dora-frontend/src/typeck/lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::sema::{
};
use crate::typeck::function::args_compatible_fct;
use crate::typeck::CallArguments;
use crate::typeparamck::{self, ErrorReporting};
use crate::typeparamck;
use crate::{specialize_for_element, ty, SourceType, SourceTypeArray};
use dora_parser::Span;

Expand Down Expand Up @@ -71,7 +71,6 @@ pub struct MethodLookup<'a> {
ret: Option<SourceType>,
fct_parent: Option<FctParent>,
span: Option<Span>,
report_errors: bool,
}

impl<'a> MethodLookup<'a> {
Expand All @@ -91,7 +90,6 @@ impl<'a> MethodLookup<'a> {
ret: None,
fct_parent: None,
span: None,
report_errors: true,
type_param_defs: caller_type_param_defs,
}
}
Expand All @@ -112,11 +110,6 @@ impl<'a> MethodLookup<'a> {
self
}

pub fn no_error_reporting(mut self) -> MethodLookup<'a> {
self.report_errors = false;
self
}

pub fn static_method(mut self, ty: SourceType) -> MethodLookup<'a> {
self.kind = Some(LookupKind::Static(ty));
self
Expand Down Expand Up @@ -170,7 +163,7 @@ impl<'a> MethodLookup<'a> {

let fct_id = if let Some(fct_id) = fct_id {
fct_id
} else if self.report_errors {
} else {
let name = self.name.expect("name not set");
let name = self.sa.interner.str(name).to_string();

Expand All @@ -194,8 +187,6 @@ impl<'a> MethodLookup<'a> {

self.report_error(msg);
return result;
} else {
return result;
};

let fct = self.sa.fct(fct_id);
Expand Down Expand Up @@ -225,10 +216,6 @@ impl<'a> MethodLookup<'a> {
}

if !args_compatible_fct(self.sa, &*fct, args, &type_params, None) {
if !self.report_errors {
return result;
}

let fct_name = self.sa.interner.str(fct.name).to_string();
let fct_params = fct
.params_without_self()
Expand Down Expand Up @@ -292,13 +279,14 @@ impl<'a> MethodLookup<'a> {
}

fn check_tps(&self, specified_tps: &TypeParamDefinition, tps: &SourceTypeArray) -> bool {
let error = if self.report_errors {
ErrorReporting::Yes(self.file, self.span.expect("no pos"))
} else {
ErrorReporting::No
};

typeparamck::check_params(self.sa, self.type_param_defs, specified_tps, tps, error)
typeparamck::check_params(
self.sa,
self.type_param_defs,
specified_tps,
tps,
self.file,
self.span.expect("no pos"),
)
}

fn ty_name(&self, ty: &SourceType) -> String {
Expand Down
Loading

0 comments on commit 7e068cb

Please sign in to comment.