Skip to content

Commit

Permalink
frontend: Add more support for GenericAssoc
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Jan 30, 2025
1 parent 4020e59 commit a3a1309
Show file tree
Hide file tree
Showing 17 changed files with 163 additions and 65 deletions.
15 changes: 12 additions & 3 deletions dora-frontend/src/access.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::sema::{
AliasDefinitionId, ClassDefinitionId, ConstDefinitionId, EnumDefinitionId, FctDefinitionId,
FctParent, FieldId, GlobalDefinitionId, ModuleDefinitionId, Sema, StructDefinitionFieldId,
StructDefinitionId, TraitDefinitionId, Visibility,
AliasDefinitionId, ClassDefinitionId, ConstDefinitionId, Element, EnumDefinitionId,
FctDefinitionId, FctParent, FieldId, GlobalDefinitionId, ModuleDefinitionId, Sema,
StructDefinitionFieldId, StructDefinitionId, TraitDefinitionId, Visibility,
};
use crate::sym::SymbolKind;

Expand All @@ -23,6 +23,15 @@ pub fn sym_accessible_from(sa: &Sema, sym: SymbolKind, module_id: ModuleDefiniti
}
}

#[allow(unused)]
pub fn element_accessible_from(
sa: &Sema,
element: &dyn Element,
module_id: ModuleDefinitionId,
) -> bool {
accessible_from(sa, element.module_id(), element.visibility(), module_id)
}

pub fn alias_accessible_from(
sa: &Sema,
alias_id: AliasDefinitionId,
Expand Down
5 changes: 3 additions & 2 deletions dora-frontend/src/aliasck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,9 +130,10 @@ fn expand_type(
| SourceType::Float64
| SourceType::Error
| SourceType::This
| SourceType::TypeParam(..) => ty,
| SourceType::TypeParam(..)
| SourceType::GenericAssoc { .. } => ty,

SourceType::GenericAssoc { .. } | SourceType::Any | SourceType::Ptr => {
SourceType::Any | SourceType::Ptr => {
panic!("unexpected type = {:?}", ty);
}
}
Expand Down
104 changes: 67 additions & 37 deletions dora-frontend/src/parsety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,12 +101,13 @@ pub struct ParsedTypeAst {
}

#[derive(Clone, Debug)]
#[allow(unused)]
pub enum ParsedTypeKind {
This,

Regular {
symbol: Option<SymbolKind>,
kind: Option<PathKind>,
symbol: SymbolKind,
kind: PathKind,
type_arguments: Vec<ParsedTypeArgument>,
},

Expand Down Expand Up @@ -185,9 +186,9 @@ fn parse_trait_type_inner(

match &parsed_ast.kind {
ParsedTypeKind::Regular {
symbol: Some(SymbolKind::Trait(trait_id)),
kind: None,
symbol: SymbolKind::Trait(trait_id),
type_arguments,
..
} => {
let trait_ty =
convert_trait_type(sa, file_id, *trait_id, &type_arguments, allow_bindings);
Expand Down Expand Up @@ -257,15 +258,15 @@ fn parse_type_regular(
sa, table, file_id, element, allow_self, sym, node,
),

SymbolKind::TypeParam(..) => {
SymbolKind::TypeParam(id) => {
if !node.params.is_empty() {
let msg = ErrorMessage::NoTypeParamsExpected;
sa.report(file_id, node.span, msg);
}

ParsedTypeKind::Regular {
symbol: Some(sym),
kind: None,
symbol: SymbolKind::TypeParam(id),
kind: PathKind::TypeParam(id),
type_arguments: Vec::new(),
}
}
Expand All @@ -277,12 +278,19 @@ fn parse_type_regular(
}
},

PathKind::GenericAssoc { .. } => ParsedTypeKind::Regular {
symbol: None,
kind: Some(path_kind),
PathKind::GenericAssoc { trait_id, .. } => ParsedTypeKind::Regular {
symbol: SymbolKind::Trait(trait_id), // Placeholder
kind: path_kind,
type_arguments: Vec::new(),
},

PathKind::Class(..)
| PathKind::Enum(..)
| PathKind::Struct(..)
| PathKind::Alias(..)
| PathKind::Trait(..)
| PathKind::TypeParam(..) => unreachable!(),

PathKind::Self_ => ParsedTypeKind::This,
}
}
Expand Down Expand Up @@ -314,9 +322,18 @@ fn parse_type_regular_with_arguments(
type_arguments.push(ty_arg);
}

let path_kind = match symbol {
SymbolKind::Alias(id) => PathKind::Alias(id),
SymbolKind::Trait(id) => PathKind::Trait(id),
SymbolKind::Class(id) => PathKind::Class(id),
SymbolKind::Struct(id) => PathKind::Struct(id),
SymbolKind::Enum(id) => PathKind::Enum(id),
_ => unreachable!(),
};

ParsedTypeKind::Regular {
symbol: Some(symbol),
kind: None,
symbol: symbol,
kind: path_kind,
type_arguments,
}
}
Expand Down Expand Up @@ -376,29 +393,29 @@ fn convert_type_inner(sa: &Sema, file_id: SourceFileId, parsed_ty: &ParsedTypeAs
}

fn convert_type_regular(sa: &Sema, file_id: SourceFileId, parsed_ty: &ParsedTypeAst) -> SourceType {
let (sym, type_params) = match parsed_ty.kind {
let (sym, path_kind, type_params) = match parsed_ty.kind {
ParsedTypeKind::Regular {
ref symbol,
kind: None,
ref kind,
type_arguments: ref type_params,
} => (symbol.clone().expect("symbol expected"), type_params),
_ => unreachable!(),
..
} => (symbol.clone(), kind.clone(), type_params),
_ => {
unreachable!()
}
};

match sym {
SymbolKind::TypeParam(id) => {
match path_kind {
PathKind::TypeParam(id) => {
assert!(type_params.is_empty());
SourceType::TypeParam(id)
}

SymbolKind::Trait(trait_id) => {
PathKind::Trait(trait_id) => {
convert_type_regular_trait_object(sa, file_id, parsed_ty, trait_id, type_params)
}

SymbolKind::Alias(..)
| SymbolKind::Class(..)
| SymbolKind::Enum(..)
| SymbolKind::Struct(..) => {
PathKind::Alias(..) | PathKind::Class(..) | PathKind::Enum(..) | PathKind::Struct(..) => {
let mut source_type_arguments = Vec::with_capacity(type_params.len());

for ty_arg in type_params {
Expand All @@ -411,7 +428,7 @@ fn convert_type_regular(sa: &Sema, file_id: SourceFileId, parsed_ty: &ParsedType
source_type_arguments.push(ty);
}

let sym_element = get_sym_element(sa, sym.clone());
let sym_element = get_path_kind_element(sa, path_kind);
let type_param_definition = sym_element.type_param_definition();

if type_param_definition.type_param_count() == source_type_arguments.len() {
Expand All @@ -427,6 +444,16 @@ fn convert_type_regular(sa: &Sema, file_id: SourceFileId, parsed_ty: &ParsedType
}
}

PathKind::GenericAssoc {
tp_id,
trait_id,
assoc_id,
} => SourceType::GenericAssoc {
tp_id,
trait_id,
assoc_id,
},

_ => unreachable!(),
}
}
Expand Down Expand Up @@ -501,12 +528,12 @@ fn convert_type_regular_trait_object(
SourceType::TraitObject(trait_id, trait_type_params.into(), bindings.into())
}

fn get_sym_element(sa: &Sema, sym: SymbolKind) -> &dyn Element {
fn get_path_kind_element(sa: &Sema, sym: PathKind) -> &dyn Element {
match sym {
SymbolKind::Class(id) => sa.class(id),
SymbolKind::Struct(id) => sa.struct_(id),
SymbolKind::Enum(id) => sa.enum_(id),
SymbolKind::Alias(id) => sa.alias(id),
PathKind::Class(id) => sa.class(id),
PathKind::Struct(id) => sa.struct_(id),
PathKind::Enum(id) => sa.enum_(id),
PathKind::Alias(id) => sa.alias(id),
_ => unimplemented!(),
}
}
Expand Down Expand Up @@ -671,14 +698,15 @@ fn check_type_inner(
parsed_ty: &ParsedTypeAst,
) -> SourceType {
match ty.clone() {
SourceType::Any | SourceType::Ptr | SourceType::GenericAssoc { .. } => {
SourceType::Any | SourceType::Ptr => {
unreachable!()
}
SourceType::This => SourceType::This,
SourceType::Assoc(..)
| SourceType::Error
| SourceType::Unit
| SourceType::TypeParam(..) => ty,
| SourceType::TypeParam(..)
| SourceType::GenericAssoc { .. } => ty,
SourceType::Bool
| SourceType::UInt8
| SourceType::Char
Expand All @@ -687,7 +715,7 @@ fn check_type_inner(
| SourceType::Int32
| SourceType::Int64 => {
let symbol = match &parsed_ty.kind {
ParsedTypeKind::Regular { symbol, .. } => symbol.clone().expect("symbol expected"),
ParsedTypeKind::Regular { symbol, .. } => symbol.clone(),
_ => unreachable!(),
};

Expand Down Expand Up @@ -760,12 +788,13 @@ fn check_type_record(
parsed_ty: &ParsedTypeAst,
type_params: SourceTypeArray,
) -> SourceType {
let (symbol, parsed_type_params) = match parsed_ty.kind {
let (symbol, path_kind, parsed_type_params) = match parsed_ty.kind {
ParsedTypeKind::Regular {
ref symbol,
ref kind,
type_arguments: ref type_params,
..
} => (symbol.clone().expect("symbol expected"), type_params),
} => (symbol.clone(), kind.clone(), type_params),
_ => unreachable!(),
};

Expand All @@ -790,7 +819,7 @@ fn check_type_record(
}

let new_type_params = SourceTypeArray::with(new_type_params);
let callee_element = get_sym_element(sa, symbol.clone());
let callee_element = get_path_kind_element(sa, path_kind);
let callee_type_param_definition = callee_element.type_param_definition();

if check_type_params(
Expand Down Expand Up @@ -1159,10 +1188,11 @@ fn expand_st(
| SourceType::Float32
| SourceType::Float64
| SourceType::Error
| SourceType::TypeParam(..) => ty,
| SourceType::TypeParam(..)
| SourceType::GenericAssoc { .. } => ty,
SourceType::This => replace_self.expect("self expected"),

SourceType::Any | SourceType::Ptr | SourceType::GenericAssoc { .. } => {
SourceType::Any | SourceType::Ptr => {
panic!("unexpected type = {:?}", ty);
// unreachable!()
}
Expand Down
12 changes: 9 additions & 3 deletions dora-frontend/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@ use dora_parser::{ast, Span};

use crate::access::sym_accessible_from;
use crate::sema::{
parent_element_or_self, AliasDefinitionId, Element, Sema, SourceFileId, TraitDefinitionId,
TypeParamId,
parent_element_or_self, AliasDefinitionId, ClassDefinitionId, Element, EnumDefinitionId, Sema,
SourceFileId, StructDefinitionId, TraitDefinitionId, TypeParamId,
};
use crate::{ErrorMessage, ModuleSymTable, Name, SymbolKind};

#[derive(Clone, Debug)]
pub enum PathKind {
Self_,
Class(ClassDefinitionId),
Enum(EnumDefinitionId),
Struct(StructDefinitionId),
Trait(TraitDefinitionId),
Alias(AliasDefinitionId),
TypeParam(TypeParamId),
GenericAssoc {
tp_id: TypeParamId,
trait_id: TraitDefinitionId,
Expand Down Expand Up @@ -142,7 +148,7 @@ fn parse_path_ident(

if available.len() == 1 {
let (trait_id, assoc_id) = available.pop().expect("element expected");
previous_sym = SymbolKind::Alias(available[0].1);
previous_sym = SymbolKind::Alias(assoc_id);
result = Some(PathKind::GenericAssoc {
tp_id: id,
trait_id,
Expand Down
4 changes: 4 additions & 0 deletions dora-frontend/src/sema/aliases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,10 @@ impl Element for AliasDefinition {
fn self_ty(&self, _sa: &Sema) -> Option<SourceType> {
None
}

fn visibility(&self) -> Visibility {
self.visibility
}
}

pub struct AliasBound {
Expand Down
4 changes: 4 additions & 0 deletions dora-frontend/src/sema/classes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ impl Element for ClassDefinition {
fn self_ty(&self, _sa: &Sema) -> Option<SourceType> {
Some(self.ty())
}

fn visibility(&self) -> Visibility {
self.visibility
}
}

impl ElementAccess for ClassDefinition {
Expand Down
4 changes: 4 additions & 0 deletions dora-frontend/src/sema/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ impl Element for ConstDefinition {
fn self_ty(&self, _sa: &Sema) -> Option<SourceType> {
None
}

fn visibility(&self) -> Visibility {
self.visibility
}
}

#[derive(Clone, Debug, PartialEq)]
Expand Down
5 changes: 3 additions & 2 deletions dora-frontend/src/sema/elements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use crate::sema::{
EnumDefinitionId, ExtensionDefinitionId, FctDefinition, FctDefinitionId, FctParent,
GlobalDefinitionId, ImplDefinition, ImplDefinitionId, ModuleDefinitionId, PackageDefinitionId,
Sema, SourceFileId, StructDefinitionId, TraitDefinition, TraitDefinitionId,
TypeParamDefinition, UseDefinitionId,
TypeParamDefinition, UseDefinitionId, Visibility,
};
use crate::{Name, SourceType, Span};

Expand All @@ -34,6 +34,7 @@ pub trait Element {
fn module_id(&self) -> ModuleDefinitionId;
fn package_id(&self) -> PackageDefinitionId;
fn type_param_definition(&self) -> &Rc<TypeParamDefinition>;
fn visibility(&self) -> Visibility;

fn is_trait(&self) -> bool {
self.to_trait().is_some()
Expand Down Expand Up @@ -66,7 +67,7 @@ pub trait Element {
fn self_ty(&self, sa: &Sema) -> Option<SourceType>;
}

pub trait ElementAccess {
pub trait ElementAccess: Element {
type Id;

fn by_id(sa: &Sema, id: Self::Id) -> &Self;
Expand Down
4 changes: 4 additions & 0 deletions dora-frontend/src/sema/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ impl Element for EnumDefinition {
let type_params = new_identity_type_params(type_params);
Some(SourceType::Enum(self.id(), type_params))
}

fn visibility(&self) -> Visibility {
self.visibility
}
}

impl ElementAccess for EnumDefinition {
Expand Down
4 changes: 4 additions & 0 deletions dora-frontend/src/sema/extensions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,8 @@ impl Element for ExtensionDefinition {
fn self_ty(&self, _sa: &Sema) -> Option<SourceType> {
Some(self.ty())
}

fn visibility(&self) -> super::Visibility {
unreachable!()
}
}
Loading

0 comments on commit a3a1309

Please sign in to comment.