Skip to content

Commit

Permalink
frontend: Change Assoc type definition
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Feb 20, 2025
1 parent 380217e commit 9eb8212
Show file tree
Hide file tree
Showing 26 changed files with 128 additions and 132 deletions.
13 changes: 2 additions & 11 deletions dora-bytecode/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,18 +282,9 @@ impl<'a> std::fmt::Display for BytecodeTypePrinter<'a> {

BytecodeType::This => write!(f, "Self"),

BytecodeType::Assoc(assoc_id, type_params) => {
BytecodeType::Assoc { assoc_id, .. } => {
let alias = self.prog.alias(*assoc_id);
write!(f, "Self::{}", alias.name)?;
if !type_params.is_empty() {
write!(
f,
"[{}]",
fmt_type_list(self.prog, &type_params, self.type_params)
)
} else {
Ok(())
}
write!(f, "Self::{}", alias.name)
}

BytecodeType::TypeAlias(..) | BytecodeType::GenericAssoc { .. } => unimplemented!(),
Expand Down
6 changes: 5 additions & 1 deletion dora-bytecode/src/dumper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ impl<'a> Display for BytecodeTypePrinter<'a> {
fmt_ty(self.prog, return_ty)
)
}
BytecodeType::TypeAlias(alias_id) | BytecodeType::Assoc(alias_id, ..) => {
BytecodeType::TypeAlias(alias_id) => {
let alias = self.prog.alias(*alias_id);
write!(f, "{}", alias.name)?;
if let Some(ref ty) = alias.ty {
Expand All @@ -370,6 +370,10 @@ impl<'a> Display for BytecodeTypePrinter<'a> {
Ok(())
}
}
BytecodeType::Assoc { assoc_id, .. } => {
let alias = self.prog.alias(*assoc_id);
write!(f, "{}", alias.name)
}
BytecodeType::GenericAssoc {
type_param_id,
assoc_id,
Expand Down
9 changes: 6 additions & 3 deletions dora-bytecode/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ pub enum BytecodeType {
TraitObject(TraitId, BytecodeTypeArray, BytecodeTypeArray),
Lambda(BytecodeTypeArray, Box<BytecodeType>),
TypeAlias(AliasId),
Assoc(AliasId, BytecodeTypeArray),
Assoc {
trait_ty: BytecodeTraitType,
assoc_id: AliasId,
},
GenericAssoc {
type_param_id: u32,
trait_ty: BytecodeTraitType,
Expand Down Expand Up @@ -52,7 +55,7 @@ impl BytecodeType {
BytecodeType::TraitObject(..) => BytecodeTypeKind::TraitObject,
BytecodeType::Lambda(..) => BytecodeTypeKind::Lambda,
BytecodeType::TypeAlias(..) => BytecodeTypeKind::TypeAlias,
BytecodeType::Assoc(..) => BytecodeTypeKind::Assoc,
BytecodeType::Assoc { .. } => BytecodeTypeKind::Assoc,
BytecodeType::GenericAssoc { .. } => BytecodeTypeKind::GenericAssoc,
BytecodeType::This => unreachable!(),
}
Expand Down Expand Up @@ -175,7 +178,7 @@ impl BytecodeType {
BytecodeType::TypeParam(_) => false,
BytecodeType::TypeAlias(..)
| BytecodeType::GenericAssoc { .. }
| BytecodeType::Assoc(..)
| BytecodeType::Assoc { .. }
| BytecodeType::This => {
unreachable!()
}
Expand Down
2 changes: 1 addition & 1 deletion 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::Assoc(id, _type_params) => {
SourceType::Alias(id, ..) | SourceType::Assoc { assoc_id: id, .. } => {
let alias = sa.alias(*id);
let found_cycle = detect_cycles_for_alias(sa, visited, visiting, context, alias);

Expand Down
6 changes: 3 additions & 3 deletions dora-frontend/src/extensiondefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,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(..) | SourceType::GenericAssoc { .. } => unimplemented!(),
SourceType::Assoc { .. } | SourceType::GenericAssoc { .. } => unimplemented!(),
}
}

Expand All @@ -105,7 +105,7 @@ impl<'x> ExtensionCheck<'x> {
SourceType::Any
| SourceType::Ptr
| SourceType::This
| SourceType::Assoc(..)
| SourceType::Assoc { .. }
| SourceType::GenericAssoc { .. } => {
unreachable!()
}
Expand Down Expand Up @@ -243,7 +243,7 @@ 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(..) | SourceType::GenericAssoc { .. } => {
SourceType::Alias(..) | SourceType::Assoc { .. } | SourceType::GenericAssoc { .. } => {
unreachable!()
}
}
Expand Down
19 changes: 8 additions & 11 deletions dora-frontend/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3483,13 +3483,10 @@ 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),
)
}
SourceType::Assoc { trait_ty, assoc_id } => BytecodeType::Assoc {
trait_ty: convert_trait_type(&trait_ty),
assoc_id: AliasId(assoc_id.index().try_into().expect("overflow")),
},
SourceType::GenericAssoc {
tp_id,
trait_ty,
Expand Down Expand Up @@ -3541,10 +3538,10 @@ pub fn register_bty_from_ty(ty: SourceType) -> BytecodeType {
trait_ty: convert_trait_type(&trait_ty),
assoc_id: AliasId(assoc_id.index().try_into().expect("overflow")),
},
SourceType::Assoc(assoc_id, type_params) => BytecodeType::Assoc(
AliasId(assoc_id.index().try_into().expect("overflow")),
bty_array_from_ty(&type_params),
),
SourceType::Assoc { trait_ty, assoc_id } => BytecodeType::Assoc {
trait_ty: convert_trait_type(&trait_ty),
assoc_id: AliasId(assoc_id.index().try_into().expect("overflow")),
},
_ => panic!("SourceType {:?} cannot be converted to BytecodeType", ty),
}
}
Expand Down
7 changes: 3 additions & 4 deletions dora-frontend/src/impldefck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ fn check_impl_definition(sa: &Sema, impl_: &ImplDefinition) {
SourceType::Any
| SourceType::Ptr
| SourceType::This
| SourceType::Assoc(..)
| SourceType::Assoc { .. }
| SourceType::GenericAssoc { .. } => {
unreachable!()
}
Expand Down Expand Up @@ -437,9 +437,8 @@ fn trait_and_impl_arg_ty_compatible(
}
}

SourceType::Assoc(id, type_params) => {
assert!(type_params.is_empty());
let ty = trait_alias_map.get(&id).unwrap_or(&SourceType::Error);
SourceType::Assoc { assoc_id, .. } => {
let ty = trait_alias_map.get(&assoc_id).unwrap_or(&SourceType::Error);
ty.allows(sa, impl_arg_ty)
}

Expand Down
17 changes: 10 additions & 7 deletions dora-frontend/src/parsety.rs
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,12 @@ fn ty_for_sym(sa: &Sema, sym: SymbolKind, type_params: SourceTypeArray) -> Sourc
if alias.parent.is_none() {
SourceType::Alias(id, type_params)
} else {
SourceType::Assoc(id, type_params)
let trait_id = alias.parent.to_trait_id().expect("trait expected");
let trait_ty = TraitType::from_trait_id(trait_id);
SourceType::Assoc {
trait_ty,
assoc_id: id,
}
}
}
_ => unimplemented!(),
Expand Down Expand Up @@ -731,7 +736,7 @@ fn check_type_inner(
unreachable!()
}
SourceType::This => SourceType::This,
SourceType::Assoc(..)
SourceType::Assoc { .. }
| SourceType::Error
| SourceType::Unit
| SourceType::TypeParam(..)
Expand Down Expand Up @@ -1200,14 +1205,12 @@ fn expand_st(
expand_st(sa, element, alias_ty, replace_self)
}

SourceType::Assoc(id, type_params) => {
let alias = sa.alias(*id);
let trait_id = alias.parent.to_trait_id().expect("trait expected");
assert!(type_params.is_empty());
SourceType::Assoc { trait_ty, assoc_id } => {
let trait_id = trait_ty.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();
let impl_alias_id = impl_.trait_alias_map().get(&assoc_id).cloned();
if let Some(impl_alias_id) = impl_alias_id {
let impl_alias = sa.alias(impl_alias_id);
expand_st(sa, element, impl_alias.ty(), replace_self)
Expand Down
2 changes: 1 addition & 1 deletion dora-frontend/src/sema/impl_matching.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ pub fn implements_trait(

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

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

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 @@ -236,7 +236,7 @@ fn match_concrete_types(
_ => false,
},

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

Expand Down
65 changes: 37 additions & 28 deletions dora-frontend/src/specialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,42 @@ pub fn specialize_trait_type(sa: &Sema, ty: TraitType, type_params: &SourceTypeA
specialize_trait_type_generic(sa, ty, &|ty| replace_type(sa, ty, Some(type_params), None))
}

pub fn specialize_trait_type_generic<S>(_sa: &Sema, ty: TraitType, specialize: &S) -> TraitType
pub fn specialize_trait_type_generic<S>(
_sa: &Sema,
trait_ty: TraitType,
specialize: &S,
) -> TraitType
where
S: Fn(SourceType) -> SourceType,
{
let type_params = ty
let type_params = trait_ty
.type_params
.iter()
.map(|ty| specialize(ty))
.collect::<Vec<_>>();

let mut new_bindings = Vec::with_capacity(ty.bindings.len());
let mut new_bindings = Vec::with_capacity(trait_ty.bindings.len());

for (id, ty) in ty.bindings {
let ty = specialize(ty);
if SourceType::Assoc(id, SourceTypeArray::empty()) != ty {
new_bindings.push((id, ty));
for (id, ty) in &trait_ty.bindings {
let ty = specialize(ty.clone());

match ty {
SourceType::Assoc {
trait_ty: assoc_trait_ty,
assoc_id,
} if assoc_trait_ty.trait_id == trait_ty.trait_id
&& assoc_trait_ty.type_params == trait_ty.type_params
&& assoc_id == *id =>
{
// Associated type binds to itself.
}

_ => new_bindings.push((*id, ty)),
}
}

TraitType {
trait_id: ty.trait_id,
trait_id: trait_ty.trait_id,
type_params: type_params.into(),
bindings: new_bindings,
}
Expand Down Expand Up @@ -84,11 +99,6 @@ 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 @@ -123,6 +133,7 @@ pub fn replace_type(
| SourceType::Float32
| SourceType::Float64
| SourceType::Error
| SourceType::Assoc { .. }
| SourceType::GenericAssoc { .. } => ty,

SourceType::Any | SourceType::Ptr => unreachable!(),
Expand Down Expand Up @@ -180,9 +191,8 @@ pub fn specialize_ty_for_call(
specialize_ty_for_call_array(sa, alias_type_params, caller_element, call_data),
),

SourceType::Assoc(alias_id, alias_type_params) => {
let alias = sa.alias(alias_id);
assert!(alias_type_params.is_empty());
SourceType::Assoc { assoc_id, .. } => {
let alias = sa.alias(assoc_id);

match &call_data.object_ty {
SourceType::TraitObject(_trait_id, _type_params, assoc_types) => {
Expand Down Expand Up @@ -216,7 +226,9 @@ pub fn specialize_ty_for_call(
caller_fct.trait_id(),
assoc.parent.to_trait_id().expect("expected trait")
);
SourceType::Assoc(assoc_id, SourceTypeArray::empty())

let trait_ty = TraitType::from_trait_id(caller_fct.trait_id());
SourceType::Assoc { trait_ty, assoc_id }
} else if let Some(impl_match) = find_impl(
sa,
caller_element,
Expand Down Expand Up @@ -349,9 +361,8 @@ pub fn specialize_ty_for_trait_object(
),
),

SourceType::Assoc(alias_id, alias_type_params) => {
let alias = sa.alias(alias_id);
assert!(alias_type_params.is_empty());
SourceType::Assoc { assoc_id, .. } => {
let alias = sa.alias(assoc_id);
assoc_types[alias.idx_in_trait()].clone()
}

Expand Down Expand Up @@ -484,10 +495,9 @@ pub fn specialize_ty_for_default_trait_method(
),
),

SourceType::Assoc(assoc_id, assoc_type_params) => {
SourceType::Assoc { assoc_id, .. } => {
let assoc = sa.alias(assoc_id);
assert!(assoc.parent.is_trait());
assert!(assoc_type_params.is_empty());

let impl_alias_id = impl_.trait_alias_map().get(&assoc_id).cloned();

Expand Down Expand Up @@ -720,18 +730,17 @@ pub fn specialize_ty_for_generic(
),
),

SourceType::Assoc(alias_id, alias_type_params) => {
let alias = sa.alias(alias_id);
SourceType::Assoc { assoc_id, .. } => {
let alias = sa.alias(assoc_id);
assert_eq!(alias.parent, AliasParent::Trait(trait_ty.trait_id));
assert!(alias_type_params.is_empty());

if let Some((_, ty)) = trait_ty.bindings.iter().find(|(x, _)| *x == alias_id) {
if let Some((_, ty)) = trait_ty.bindings.iter().find(|(x, _)| *x == assoc_id) {
ty.clone()
} else {
SourceType::GenericAssoc {
tp_id: type_param_id,
trait_ty: trait_ty.clone(),
assoc_id: alias_id,
assoc_id,
}
}
}
Expand Down Expand Up @@ -956,7 +965,7 @@ pub fn specialize_for_element(
}
}

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

Expand Down
Loading

0 comments on commit 9eb8212

Please sign in to comment.