Skip to content

Commit

Permalink
frontend: Add error message for index traits
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Nov 12, 2024
1 parent e62d456 commit 67537a5
Show file tree
Hide file tree
Showing 15 changed files with 367 additions and 178 deletions.
8 changes: 8 additions & 0 deletions dora-frontend/src/error/msg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ pub enum ErrorMessage {
FieldShouldBeUnnamed,
OldClassDefinition,
ExpectedNamedPattern,
IndexGetNotImplemented(String),
IndexSetNotImplemented(String),
}

impl ErrorMessage {
Expand Down Expand Up @@ -735,6 +737,12 @@ impl ErrorMessage {
ErrorMessage::ExpectedNamedPattern => {
format!("Expected named pattern field.")
}
ErrorMessage::IndexGetNotImplemented(ref ty) => {
format!("Type `{}` does not implement trait IndexGet.", ty)
}
ErrorMessage::IndexSetNotImplemented(ref ty) => {
format!("Type `{}` does not implement trait IndexGet.", ty)
}
}
}
}
Expand Down
16 changes: 0 additions & 16 deletions dora-frontend/src/fctdefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,6 @@ use crate::ErrorMessage;

pub fn check(sa: &Sema) {
for (_id, fct) in sa.fcts.iter() {
for p in fct.params_without_self() {
let ast_node = p.ast.as_ref().expect("missing ast");

if fct.is_variadic() {
sa.report(
fct.file_id,
ast_node.span,
ErrorMessage::VariadicParameterNeedsToBeLast,
);
}

if ast_node.variadic {
fct.is_variadic.set(true);
}
}

check_test(sa, &*fct);
}
}
Expand Down
4 changes: 2 additions & 2 deletions dora-frontend/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1805,7 +1805,7 @@ impl<'a> AstBytecodeGen<'a> {
};

// Calculate number of non-variadic arguments
let non_variadic_arguments = if callee.is_variadic.get() {
let non_variadic_arguments = if callee.params.is_variadic() {
arg_types.len() - arg_start_offset - 1
} else {
arg_types.len()
Expand All @@ -1817,7 +1817,7 @@ impl<'a> AstBytecodeGen<'a> {
registers.push(reg);
}

if callee.is_variadic.get() {
if callee.params.is_variadic() {
let array_reg = self.emit_array_with_variadic_arguments(
expr,
arg_types,
Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/impldefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ pub fn check_definition_against_trait(sa: &mut Sema) {
let self_ty = Some(impl_.extended_ty());
let params = trait_method.params.clone();

for param in &params {
for param in &params.params {
param.set_ty(replace_type(sa, param.ty(), None, self_ty.clone()));
}

Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/program_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ fn create_functions(sa: &Sema, e: &mut Emitter) -> Vec<FunctionData> {
is_internal: fct.is_internal,
is_test: fct.is_test,
is_optimize_immediately: fct.is_optimize_immediately,
is_variadic: fct.is_variadic.get(),
is_variadic: fct.params.is_variadic(),
is_force_inline: fct.is_force_inline,
is_never_inline: fct.is_never_inline,
bytecode: fct.bytecode.get().cloned(),
Expand Down
47 changes: 34 additions & 13 deletions dora-frontend/src/program_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use crate::sema::{
EnumDefinition, EnumField, EnumVariant, ExtensionDefinition, ExtensionDefinitionId,
FctDefinition, FctDefinitionId, FctParent, Field, FieldId, GlobalDefinition, ImplDefinition,
ImplDefinitionId, ModuleDefinition, ModuleDefinitionId, PackageDefinition, PackageDefinitionId,
PackageName, Param, Sema, SourceFile, SourceFileId, StructDefinition, StructDefinitionField,
StructDefinitionFieldId, TraitDefinition, TraitDefinitionId, TypeParamDefinition,
UseDefinition, Visibility,
PackageName, Param, Params, Sema, SourceFile, SourceFileId, StructDefinition,
StructDefinitionField, StructDefinitionFieldId, TraitDefinition, TraitDefinitionId,
TypeParamDefinition, UseDefinition, Visibility,
};
use crate::sym::{SymTable, Symbol, SymbolKind};
use crate::{report_sym_shadow_span, ty, ParsedType, SourceType};
Expand Down Expand Up @@ -529,7 +529,7 @@ impl<'x> visit::Visitor for TopLevelDeclaration<'x> {
.set(extension_id)
.is_ok());

find_elements_in_extension(self.sa, extension_id, node);
find_elements_in_extension(self.sa, self.file_id, extension_id, node);
}
}

Expand Down Expand Up @@ -701,7 +701,7 @@ impl<'x> visit::Visitor for TopLevelDeclaration<'x> {
);

let parent = FctParent::None;
let params = parse_function_params(self.sa, node, parent.clone(), &modifiers);
let params = parse_function_params(self.sa, self.file_id, node, parent.clone(), &modifiers);

let fct = FctDefinition::new(
self.package_id,
Expand Down Expand Up @@ -912,7 +912,8 @@ fn find_elements_in_trait(
);

let parent = FctParent::Trait(trait_id);
let params = parse_function_params(sa, method_node, parent.clone(), &modifiers);
let params =
parse_function_params(sa, file_id, method_node, parent.clone(), &modifiers);

let fct = FctDefinition::new(
trait_.package_id,
Expand Down Expand Up @@ -1081,7 +1082,8 @@ fn find_elements_in_impl(
);

let parent = FctParent::Impl(impl_id);
let params = parse_function_params(sa, method_node, parent.clone(), &modifiers);
let params =
parse_function_params(sa, file_id, method_node, parent.clone(), &modifiers);

let fct = FctDefinition::new(
impl_.package_id,
Expand Down Expand Up @@ -1180,6 +1182,7 @@ fn find_elements_in_impl(

fn find_elements_in_extension(
sa: &mut Sema,
file_id: SourceFileId,
extension_id: ExtensionDefinitionId,
node: &Arc<ast::Impl>,
) {
Expand Down Expand Up @@ -1213,7 +1216,8 @@ fn find_elements_in_extension(
);

let parent = FctParent::Extension(extension_id);
let params = parse_function_params(sa, method_node, parent.clone(), &modifiers);
let params =
parse_function_params(sa, file_id, method_node, parent.clone(), &modifiers);

let fct = FctDefinition::new(
extension.package_id,
Expand Down Expand Up @@ -1529,16 +1533,19 @@ fn parse_type_param_definition(
}

fn parse_function_params(
_sa: &Sema,
sa: &Sema,
file_id: SourceFileId,
ast: &ast::Function,
parent: FctParent,
modifiers: &ParsedModifierList,
) -> Vec<Param> {
) -> Params {
let mut params: Vec<Param> = Vec::new();
let mut has_self = false;

match parent {
FctParent::Impl(..) | FctParent::Extension(..) | FctParent::Trait(..) => {
if !modifiers.is_static {
has_self = true;
params.push(Param::new_ty(SourceType::This));
}
}
Expand All @@ -1548,12 +1555,26 @@ fn parse_function_params(
FctParent::Function => unreachable!(),
}

for p in &ast.params {
let param = Param::new(p.clone());
let mut is_variadic = false;

for (idx, ast_param) in ast.params.iter().enumerate() {
if ast_param.variadic {
if idx + 1 == ast.params.len() {
is_variadic = true;
} else {
sa.report(
file_id,
ast_param.span,
ErrorMessage::VariadicParameterNeedsToBeLast,
);
}
}

let param = Param::new(ast_param.clone());
params.push(param);
}

params
Params::new(params, has_self, is_variadic)
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/sema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ pub use self::elements::{
pub use self::enums::{EnumDefinition, EnumDefinitionId, EnumField, EnumVariant};
pub use self::extensions::{ExtensionDefinition, ExtensionDefinitionId};
pub use self::functions::{
emit_as_bytecode_operation, FctDefinition, FctDefinitionId, FctParent, Intrinsic, Param,
emit_as_bytecode_operation, FctDefinition, FctDefinitionId, FctParent, Intrinsic, Param, Params,
};
pub use self::globals::{GlobalDefinition, GlobalDefinitionId};
pub use self::impl_matching::{find_impl, impl_matches, implements_trait, maybe_alias_ty};
Expand Down
52 changes: 41 additions & 11 deletions dora-frontend/src/sema/functions.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::cell::{Cell, OnceCell};
use std::cell::OnceCell;
use std::rc::Rc;
use std::sync::Arc;

Expand Down Expand Up @@ -37,9 +37,8 @@ pub struct FctDefinition {
pub is_internal: bool,
pub is_force_inline: bool,
pub is_never_inline: bool,
pub params: Vec<Param>,
pub params: Params,
pub return_type: ParsedType,
pub is_variadic: Cell<bool>,

pub analysis: OnceCell<AnalysisData>,

Expand All @@ -58,7 +57,7 @@ impl FctDefinition {
modifiers: ParsedModifierList,
name: Name,
type_params: Rc<TypeParamDefinition>,
params: Vec<Param>,
params: Params,
parent: FctParent,
) -> FctDefinition {
let return_type = if let Some(ref ast_return_type) = ast.return_type {
Expand Down Expand Up @@ -86,7 +85,6 @@ impl FctDefinition {
is_internal: modifiers.is_internal,
is_force_inline: modifiers.is_force_inline,
is_never_inline: modifiers.is_never_inline,
is_variadic: Cell::new(false),
analysis: OnceCell::new(),
type_param_definition: type_params,
container_type_params: OnceCell::new(),
Expand Down Expand Up @@ -181,10 +179,6 @@ impl FctDefinition {
self.ast.kind.is_lambda()
}

pub fn is_variadic(&self) -> bool {
self.is_variadic.get()
}

pub fn span(&self) -> Span {
self.span
}
Expand All @@ -202,7 +196,7 @@ impl FctDefinition {
}

pub fn params_with_self(&self) -> &[Param] {
&self.params
&self.params.params
}

pub fn params_without_self(&self) -> &[Param] {
Expand All @@ -215,7 +209,7 @@ impl FctDefinition {

pub fn self_param(&self) -> Option<&Param> {
if self.has_hidden_self_argument() {
Some(&self.params[0])
Some(&self.params.params[0])
} else {
None
}
Expand Down Expand Up @@ -349,6 +343,42 @@ impl FctParent {
}
}

#[derive(Debug, Clone)]
pub struct Params {
pub params: Vec<Param>,
pub has_self: bool,
pub is_variadic: bool,
}

impl Params {
pub fn new(params: Vec<Param>, has_self: bool, is_variadic: bool) -> Params {
Params {
params,
has_self,
is_variadic,
}
}

pub fn regular_params(&self) -> &[Param] {
let start = self.has_self as usize;
let end = self.params.len() - self.is_variadic as usize;

&self.params[start..end]
}

pub fn variadic_param(&self) -> Option<&Param> {
if self.is_variadic() {
Some(self.params.last().expect("missing param"))
} else {
None
}
}

pub fn is_variadic(&self) -> bool {
self.is_variadic
}
}

#[derive(Debug, Clone)]
pub struct Param {
pub ast: Option<Arc<ast::Param>>,
Expand Down
15 changes: 4 additions & 11 deletions 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, find_method};
use crate::typeck::call::{check_expr_call, create_call_arguments, find_method};
use crate::typeck::constck::ConstCheck;
pub use crate::typeck::control::is_pattern_check;
use crate::typeck::control::{
Expand All @@ -17,8 +17,9 @@ use crate::typeck::control::{
use crate::typeck::expr::{check_expr, read_ident, read_path, read_path_expr};
pub use crate::typeck::expr::{compute_lit_float, compute_lit_int};
use crate::typeck::function::{
add_local, args_compatible, args_compatible_fct, check_lit_char, check_lit_float,
check_lit_int, check_lit_str, is_simple_enum, TypeCheck, VarManager,
add_local, arg_allows, args_compatible, args_compatible_fct, check_args_compatible,
check_args_compatible_fct, check_lit_char, check_lit_float, check_lit_int, check_lit_str,
is_simple_enum, TypeCheck, VarManager,
};
pub use crate::typeck::lookup::find_method_call_candidates;
use crate::typeck::lookup::MethodLookup;
Expand Down Expand Up @@ -203,18 +204,10 @@ impl CallArguments {
}
}

self.positional_types(ck)
}

fn positional_types(&self, ck: &TypeCheck) -> Vec<SourceType> {
self.arguments
.iter()
.filter(|a| a.name.is_none())
.map(|p| ck.analysis.ty(p.id))
.collect::<Vec<SourceType>>()
}

fn len(&self) -> usize {
self.arguments.len()
}
}
Loading

0 comments on commit 67537a5

Please sign in to comment.