Skip to content

Commit

Permalink
frontend: Preparing for using Assoc type
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Oct 13, 2024
1 parent 82d4e0f commit b3151c4
Show file tree
Hide file tree
Showing 25 changed files with 268 additions and 75 deletions.
2 changes: 2 additions & 0 deletions dora-boots/bytecode/opcode.dora
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ pub const BC_TYPE_CLASS: Int32 = 13;
pub const BC_TYPE_TRAIT_OBJECT: Int32 = 14;
pub const BC_TYPE_LAMBDA: Int32 = 15;
pub const BC_TYPE_TYPE_ALIAS: Int32 = 16;
pub const BC_TYPE_ASSOC: Int32 = 17;

pub const CONSTPOOL_OPCODE_STRING: Int32 = 0;
pub const CONSTPOOL_OPCODE_FLOAT32: Int32 = 1;
Expand Down Expand Up @@ -341,6 +342,7 @@ pub fn bytecodeTypeName(code: Int32): String {
if code == BC_TYPE_TRAIT_OBJECT { return "TraitObject"; }
if code == BC_TYPE_LAMBDA { return "Lambda"; }
if code == BC_TYPE_TYPE_ALIAS { return "TypeAlias"; }
if code == BC_TYPE_ASSOC { return "Assoc"; }
unreachable[String]()
}

Expand Down
1 change: 1 addition & 0 deletions dora-bytecode/src/data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub enum BytecodeTypeKind {
TraitObject,
Lambda,
TypeAlias,
Assoc,
}

#[derive(IntoPrimitive, TryFromPrimitive, Copy, Clone, PartialEq, Eq)]
Expand Down
2 changes: 1 addition & 1 deletion dora-bytecode/src/dumper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ impl<'a> Display for BytecodeTypePrinter<'a> {
fmt_ty(self.prog, return_ty)
)
}
BytecodeType::TypeAlias(alias_id) => {
BytecodeType::TypeAlias(alias_id) | BytecodeType::Assoc(alias_id, ..) => {
let alias = &self.prog.aliases[alias_id.0 as usize];
write!(f, "{}", alias.name)?;
if let Some(ref ty) = alias.ty {
Expand Down
6 changes: 5 additions & 1 deletion dora-bytecode/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub enum BytecodeType {
TraitObject(TraitId, BytecodeTypeArray),
Lambda(BytecodeTypeArray, Box<BytecodeType>),
TypeAlias(AliasId),
Assoc(AliasId, BytecodeTypeArray),
}

impl BytecodeType {
Expand All @@ -46,6 +47,7 @@ impl BytecodeType {
BytecodeType::TraitObject(..) => BytecodeTypeKind::TraitObject,
BytecodeType::Lambda(..) => BytecodeTypeKind::Lambda,
BytecodeType::TypeAlias(..) => BytecodeTypeKind::TypeAlias,
BytecodeType::Assoc(..) => BytecodeTypeKind::Assoc,
BytecodeType::This => unreachable!(),
}
}
Expand Down Expand Up @@ -170,7 +172,9 @@ impl BytecodeType {
return_type.is_concrete_type()
}
BytecodeType::TypeParam(_) => false,
BytecodeType::TypeAlias(..) | BytecodeType::This => unreachable!(),
BytecodeType::TypeAlias(..) | BytecodeType::Assoc(..) | BytecodeType::This => {
unreachable!()
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions dora-frontend/src/aliasck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ fn expand_type(
SourceType::Tuple(expand_sta(sa, subtypes, visited, visiting, context))
}

SourceType::Alias(id, _type_params) => {
SourceType::Alias(id, _type_params) | SourceType::Assoc(id, _type_params) => {
let alias = sa.alias(*id);
let found_cycle = detect_cycles_for_alias(sa, visited, visiting, context, alias);

Expand All @@ -132,7 +132,7 @@ fn expand_type(
| SourceType::This
| SourceType::TypeParam(..) => ty,

SourceType::Assoc(..) | SourceType::Any | SourceType::Ptr => {
SourceType::GenericAssoc(..) | SourceType::Any | SourceType::Ptr => {
panic!("unexpected type = {:?}", ty);
}
}
Expand Down
12 changes: 9 additions & 3 deletions dora-frontend/src/extensiondefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub fn package_for_type(sa: &Sema, ty: SourceType) -> Option<PackageDefinitionId
SourceType::Enum(id, ..) => Some(sa.enum_(id).package_id),
SourceType::TraitObject(id, ..) => Some(sa.trait_(id).package_id),
SourceType::Alias(id, ..) => Some(sa.alias(id).package_id),
SourceType::Assoc(..) => unimplemented!(),
SourceType::Assoc(..) | SourceType::GenericAssoc(..) => unimplemented!(),
}
}

Expand All @@ -101,7 +101,11 @@ impl<'x> ExtensionCheck<'x> {
);
}
SourceType::Alias(..) => unimplemented!(),
SourceType::Any | SourceType::Ptr | SourceType::This | SourceType::Assoc(..) => {
SourceType::Any
| SourceType::Ptr
| SourceType::This
| SourceType::Assoc(..)
| SourceType::GenericAssoc(..) => {
unreachable!()
}
SourceType::Error
Expand Down Expand Up @@ -238,7 +242,9 @@ fn discover_type_params(sa: &Sema, ty: SourceType, used_type_params: &mut FixedB
SourceType::TypeParam(tp_id) => {
used_type_params.insert(tp_id.index());
}
SourceType::Alias(..) | SourceType::Assoc(..) => unreachable!(),
SourceType::Alias(..) | SourceType::Assoc(..) | SourceType::GenericAssoc(..) => {
unreachable!()
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions dora-frontend/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3246,6 +3246,13 @@ pub fn bty_from_ty(ty: SourceType) -> BytecodeType {
assert!(type_params.is_empty());
BytecodeType::TypeAlias(AliasId(id.index().try_into().expect("overflow")))
}
SourceType::Assoc(id, type_params) => {
assert!(type_params.is_empty());
BytecodeType::Assoc(
AliasId(id.index().try_into().expect("overflow")),
bty_array_from_ty(&type_params),
)
}
_ => panic!("SourceType {:?} cannot be converted to BytecodeType", ty),
}
}
Expand Down
14 changes: 12 additions & 2 deletions dora-frontend/src/impldefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@ pub fn check_definition(sa: &Sema) {
fn check_impl_definition(sa: &Sema, impl_: &ImplDefinition) {
match impl_.extended_ty() {
SourceType::Alias(..) => unimplemented!(),
SourceType::Any | SourceType::Ptr | SourceType::This | SourceType::Assoc(..) => {
SourceType::Any
| SourceType::Ptr
| SourceType::This
| SourceType::Assoc(..)
| SourceType::GenericAssoc(..) => {
unreachable!()
}
SourceType::Error
Expand Down Expand Up @@ -312,6 +316,12 @@ fn trait_and_impl_arg_ty_compatible(
ty == &impl_arg_ty
}

SourceType::Assoc(id, type_params) => {
assert!(type_params.is_empty());
let ty = trait_alias_map.get(&id).expect("missing alias");
ty == &impl_arg_ty
}

SourceType::TypeParam(id) => trait_type_params[id.index()] == impl_arg_ty,

SourceType::This => self_ty == impl_arg_ty,
Expand All @@ -326,7 +336,7 @@ fn trait_and_impl_arg_ty_compatible(
| SourceType::Float64
| SourceType::Error => trait_arg_ty == impl_arg_ty,

SourceType::Any | SourceType::Ptr | SourceType::Assoc(..) => unreachable!(),
SourceType::Any | SourceType::Ptr | SourceType::GenericAssoc(..) => unreachable!(),
}
}

Expand Down
87 changes: 84 additions & 3 deletions dora-frontend/src/parsety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,15 @@ fn ty_for_sym(sa: &Sema, sym: SymbolKind, type_params: SourceTypeArray) -> Sourc
}
}
SymbolKind::Enum(id) => SourceType::Enum(id, type_params),
SymbolKind::Alias(id) => SourceType::Alias(id, type_params),
SymbolKind::Alias(id) => {
let alias = sa.alias(id);

if alias.parent.is_none() {
SourceType::Alias(id, type_params)
} else {
SourceType::Alias(id, type_params)
}
}
_ => unimplemented!(),
}
}
Expand Down Expand Up @@ -661,7 +669,7 @@ fn check_type_inner(
parsed_ty: &ParsedTypeAst,
) -> SourceType {
match ty.clone() {
SourceType::Any | SourceType::Ptr | SourceType::Assoc(..) => {
SourceType::Any | SourceType::Ptr | SourceType::GenericAssoc(..) => {
unreachable!()
}
SourceType::This => SourceType::This,
Expand Down Expand Up @@ -737,6 +745,49 @@ fn check_type_inner(
| SourceType::Enum(_, type_params) => {
check_type_record(sa, element, ctxt, parsed_ty, type_params)
}
SourceType::Assoc(id, type_params) => {
let alias = sa.alias(id);
assert!(alias.parent.is_impl() || alias.parent.is_trait());

let parsed_type_params = match parsed_ty.kind {
ParsedTypeKind::Regular {
type_arguments: ref type_params,
..
} => type_params,
_ => unreachable!(),
};

assert_eq!(type_params.len(), parsed_type_params.len());
let mut new_type_params = Vec::with_capacity(parsed_type_params.len());

for idx in 0..type_params.len() {
let parsed_type_arg = &parsed_type_params[idx];
assert!(parsed_type_arg.name.is_none());
let ty = check_type_inner(
sa,
element,
ctxt,
type_params[idx].clone(),
&parsed_type_arg.ty,
);
new_type_params.push(ty);
}

let new_type_params: SourceTypeArray = new_type_params.into();

if check_type_params(
sa,
alias.type_param_definition(),
new_type_params.types(),
ctxt.file_id,
parsed_ty.span,
ctxt.type_param_definition,
) {
SourceType::Assoc(id, new_type_params)
} else {
SourceType::Error
}
}
SourceType::TraitObject(trait_id, type_params, bindings) => check_type_trait_object(
sa,
element,
Expand Down Expand Up @@ -1160,6 +1211,36 @@ fn expand_st(
}
}

SourceType::Assoc(id, type_params) => {
let alias = sa.alias(*id);

match alias.parent {
AliasParent::Trait(trait_id) => {
let element = parent_element_or_self(sa, element);
if let Some(impl_) = element.to_impl() {
let impl_alias_id = impl_.trait_alias_map().get(&id).cloned();
if let Some(impl_alias_id) = impl_alias_id {
let impl_alias = sa.alias(impl_alias_id);
impl_alias.ty()
} else {
SourceType::Error
}
} else if let Some(trait_) = element.to_trait() {
assert_eq!(trait_id, trait_.id());
ty
} else {
ty
}
}

AliasParent::Impl(..) => unreachable!(),
AliasParent::None => {
let alias_ty = replace_type(sa, alias.ty(), Some(type_params), None);
expand_st(sa, element, alias_ty, replace_self)
}
}
}

SourceType::Unit
| SourceType::UInt8
| SourceType::Bool
Expand All @@ -1172,7 +1253,7 @@ fn expand_st(
| SourceType::TypeParam(..) => ty,
SourceType::This => replace_self.expect("self expected"),

SourceType::Any | SourceType::Ptr | SourceType::Assoc(..) => {
SourceType::Any | SourceType::Ptr | SourceType::GenericAssoc(..) => {
panic!("unexpected type = {:?}", ty);
// unreachable!()
}
Expand Down
7 changes: 7 additions & 0 deletions dora-frontend/src/sema/aliases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ impl AliasParent {
_ => false,
}
}

pub fn is_none(&self) -> bool {
match self {
AliasParent::None => true,
_ => false,
}
}
}

pub struct AliasDefinition {
Expand Down
20 changes: 13 additions & 7 deletions dora-frontend/src/sema/impl_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,9 @@ pub fn implements_trait(

SourceType::TypeParam(tp_id) => check_type_param_defs.implements_trait(tp_id, trait_ty),

SourceType::Alias(..) | SourceType::Assoc(..) => unreachable!(),
SourceType::Alias(..) | SourceType::Assoc(..) | SourceType::GenericAssoc(..) => {
unreachable!()
}

SourceType::Error => false,

Expand All @@ -70,13 +72,17 @@ pub fn implements_trait(
}

pub fn maybe_alias_ty(sa: &Sema, mut ty: SourceType) -> SourceType {
while let SourceType::Alias(id, type_params) = ty {
assert!(type_params.is_empty());
let alias = sa.alias(id);
ty = alias.ty();
}
loop {
match ty {
SourceType::Alias(id, type_params) => {
assert!(type_params.is_empty());
let alias = sa.alias(id);
ty = alias.ty();
}

ty
_ => return ty,
}
}
}

pub struct ImplMatch {
Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/sema/matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ fn match_concrete_types(
_ => false,
},

SourceType::Alias(..) | SourceType::Assoc(..) => {
SourceType::Alias(..) | SourceType::Assoc(..) | SourceType::GenericAssoc(..) => {
unimplemented!()
}

Expand Down
17 changes: 14 additions & 3 deletions dora-frontend/src/specialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ pub fn replace_type(
replace_sta(sa, alias_type_params, type_params, self_ty),
),

SourceType::Assoc(alias_id, alias_type_params) => SourceType::Assoc(
alias_id,
replace_sta(sa, alias_type_params, type_params, self_ty),
),

SourceType::Lambda(params, return_type) => SourceType::Lambda(
replace_sta(sa, params, type_params, self_ty.clone()),
Box::new(replace_type(sa, *return_type, type_params, self_ty)),
Expand Down Expand Up @@ -86,7 +91,7 @@ pub fn replace_type(
| SourceType::Float64
| SourceType::Error => ty,

SourceType::Any | SourceType::Ptr | SourceType::Assoc(..) => unreachable!(),
SourceType::Any | SourceType::Ptr | SourceType::GenericAssoc(..) => unreachable!(),
}
}

Expand Down Expand Up @@ -170,7 +175,10 @@ pub fn specialize_for_element(
| SourceType::Float64
| SourceType::Error => ty,

SourceType::Any | SourceType::Ptr | SourceType::Assoc(..) => unreachable!(),
SourceType::Any
| SourceType::Ptr
| SourceType::Assoc(..)
| SourceType::GenericAssoc(..) => unreachable!(),
}
}

Expand Down Expand Up @@ -253,7 +261,10 @@ pub fn specialize_for_trait_object(sa: &Sema, ty: SourceType, trait_ty: SourceTy
| SourceType::Float64
| SourceType::Error => ty,

SourceType::Any | SourceType::Ptr | SourceType::Assoc(..) => unreachable!(),
SourceType::Any
| SourceType::Ptr
| SourceType::Assoc(..)
| SourceType::GenericAssoc(..) => unreachable!(),
}
}

Expand Down
Loading

0 comments on commit b3151c4

Please sign in to comment.