Skip to content

Commit

Permalink
bytecode: Use BytecodeTraitType for ImplData::trait_ty
Browse files Browse the repository at this point in the history
  • Loading branch information
dinfuehr committed Feb 3, 2025
1 parent 110db77 commit 3742770
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 22 deletions.
110 changes: 101 additions & 9 deletions dora-bytecode/src/display.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use crate::{
BytecodeType, BytecodeTypeArray, FunctionId, FunctionKind, ModuleId, Program, TypeParamData,
BytecodeTraitType, BytecodeType, BytecodeTypeArray, FunctionId, FunctionKind, ModuleId,
Program, TypeParamData,
};

pub fn display_fct(prog: &Program, fct_id: FunctionId) -> String {
Expand Down Expand Up @@ -67,7 +68,7 @@ pub fn display_fct(prog: &Program, fct_id: FunctionId) -> String {
}

result.push_str(" ");
result.push_str(&display_ty_with_type_params(
result.push_str(&display_trait_ty_with_type_params(
prog,
&impl_.trait_ty,
&impl_.type_params,
Expand Down Expand Up @@ -138,18 +139,44 @@ pub fn display_ty_without_type_params(prog: &Program, ty: &BytecodeType) -> Stri
printer.string()
}

pub fn fmt_ty_with_type_params<'a>(
prog: &'a Program,
ty: &'a BytecodeType,
type_params: &'a TypeParamData,
) -> BytecodeTypePrinter<'a> {
BytecodeTypePrinter {
prog,
type_params: TypeParamMode::TypeParams(type_params),
ty: ty.clone(),
}
}

pub fn display_ty_with_type_params(
prog: &Program,
ty: &BytecodeType,
type_params: &TypeParamData,
) -> String {
let printer = BytecodeTypePrinter {
fmt_ty_with_type_params(prog, ty, type_params).string()
}

pub fn fmt_trait_ty_with_type_params<'a>(
prog: &'a Program,
trait_ty: &'a BytecodeTraitType,
type_params: &'a TypeParamData,
) -> BytecodeTraitTypePrinter<'a> {
BytecodeTraitTypePrinter {
prog,
type_params: TypeParamMode::TypeParams(type_params),
ty: ty.clone(),
};
type_params,
trait_ty,
}
}

printer.string()
pub fn display_trait_ty_with_type_params(
prog: &Program,
trait_ty: &BytecodeTraitType,
type_params: &TypeParamData,
) -> String {
fmt_trait_ty_with_type_params(prog, trait_ty, type_params).string()
}

enum TypeParamMode<'a> {
Expand All @@ -158,14 +185,14 @@ enum TypeParamMode<'a> {
TypeParams(&'a TypeParamData),
}

struct BytecodeTypePrinter<'a> {
pub struct BytecodeTypePrinter<'a> {
prog: &'a Program,
type_params: TypeParamMode<'a>,
ty: BytecodeType,
}

impl<'a> BytecodeTypePrinter<'a> {
fn string(&self) -> String {
pub fn string(&self) -> String {
format!("{}", self)
}

Expand Down Expand Up @@ -269,6 +296,71 @@ impl<'a> std::fmt::Display for BytecodeTypePrinter<'a> {
}
}

pub struct BytecodeTraitTypePrinter<'a> {
prog: &'a Program,
type_params: &'a TypeParamData,
trait_ty: &'a BytecodeTraitType,
}

impl<'a> BytecodeTraitTypePrinter<'a> {
pub fn string(&self) -> String {
format!("{}", self)
}

pub fn name(
&self,
trait_ty: &BytecodeTraitType,
fmt: &mut std::fmt::Formatter,
) -> std::fmt::Result {
let trait_id = trait_ty.trait_id;
let trait_ = self.prog.trait_(trait_id);
write!(fmt, "{}", trait_.name)?;

if !trait_ty.type_params.is_empty() || !trait_ty.bindings.is_empty() {
let mut first = false;
write!(fmt, "[")?;

for ty in trait_ty.type_params.iter() {
if !first {
write!(fmt, ", ")?;
}

write!(
fmt,
"{}",
fmt_ty_with_type_params(&self.prog, &ty, self.type_params)
)?;
first = false;
}

for (alias_id, ty) in trait_ty.bindings.iter() {
if !first {
write!(fmt, ", ")?;
}

let alias = self.prog.alias(*alias_id);
write!(
fmt,
"{}={}",
alias.name,
fmt_ty_with_type_params(&self.prog, &ty, self.type_params)
)?;
first = false;
}

write!(fmt, "]")?;
}

Ok(())
}
}

impl<'a> std::fmt::Display for BytecodeTraitTypePrinter<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
self.name(&self.trait_ty, f)
}
}

pub fn module_path_name(prog: &Program, module_id: ModuleId, name: &str) -> String {
let mut result = module_path(prog, module_id);

Expand Down
2 changes: 1 addition & 1 deletion dora-bytecode/src/program.rs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ pub struct ImplId(pub u32);
pub struct ImplData {
pub module_id: ModuleId,
pub type_params: TypeParamData,
pub trait_ty: BytecodeType,
pub trait_ty: BytecodeTraitType,
pub extended_ty: BytecodeType,
pub methods: Vec<FunctionId>,
pub trait_method_map: Vec<(FunctionId, FunctionId)>,
Expand Down
13 changes: 13 additions & 0 deletions dora-bytecode/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,16 @@ pub struct BytecodeTraitType {
pub type_params: BytecodeTypeArray,
pub bindings: Vec<(AliasId, BytecodeType)>,
}

impl BytecodeTraitType {
pub fn is_trait_object_ty(&self, ty: &BytecodeType) -> bool {
match ty {
BytecodeType::TraitObject(trait_id, type_params, bindings) => {
assert!(bindings.is_empty());
self.trait_id == *trait_id && &self.type_params == type_params
}

_ => false,
}
}
}
2 changes: 1 addition & 1 deletion dora-frontend/src/program_emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ fn create_impls(sa: &Sema) -> Vec<ImplData> {
result.push(ImplData {
module_id: convert_module_id(impl_.module_id),
type_params: create_type_params(sa, impl_.type_param_definition()),
trait_ty: bty_from_ty(trait_ty.ty()),
trait_ty: convert_trait_type(&trait_ty),
extended_ty: bty_from_ty(impl_.extended_ty()),
methods,
trait_method_map,
Expand Down
1 change: 1 addition & 0 deletions dora-frontend/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,7 @@ impl TraitType {
}

pub fn ty(&self) -> SourceType {
assert!(self.bindings.is_empty());
SourceType::TraitObject(self.trait_id, self.type_params.clone(), ().into())
}

Expand Down
2 changes: 1 addition & 1 deletion dora-runtime/src/compiler/aot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ impl<'a> TransitiveClosureComputation<'a> {
let trait_type_params = trait_object_ty.type_params();

for impl_ in self.vm.program.impls.iter() {
if impl_.trait_ty == trait_object_ty {
if impl_.trait_ty.is_trait_object_ty(&trait_object_ty) {
for (trait_method_id, impl_method_id) in &impl_.trait_method_map {
if *trait_method_id == trait_fct_id {
let actual_ty = impl_.extended_ty.clone();
Expand Down
7 changes: 3 additions & 4 deletions dora-runtime/src/vm/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ pub fn find_trait_impl(
.expect("no impl found for generic trait method call");

let impl_ = vm.impl_(impl_id);
let impl_trait_id = impl_.trait_ty.trait_id().expect("expected trait type");
let impl_trait_id = impl_.trait_ty.trait_id;

assert_eq!(impl_trait_id, trait_ty.trait_id);

Expand All @@ -48,15 +48,14 @@ pub fn find_impl(
for (impl_id, impl_) in vm.program.impls.iter().enumerate() {
let impl_id = ImplId(impl_id.try_into().expect("doesn't fit"));

if impl_.trait_ty.trait_id().expect("trait expected") != trait_id {
if impl_.trait_ty.trait_id != trait_id {
continue;
}

if let Some(binding) =
impl_block_matches_ty(vm, check_ty.clone(), check_type_param_defs, impl_id)
{
let impl_trait_ty_params =
specialize_bty_array(&impl_.trait_ty.type_params(), &binding);
let impl_trait_ty_params = specialize_bty_array(&impl_.trait_ty.type_params, &binding);

if impl_trait_ty_params != trait_ty.type_params {
continue;
Expand Down
10 changes: 4 additions & 6 deletions dora-runtime/src/vm/stdlib_lookup.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,9 +195,8 @@ fn lookup_extension_for_ty(vm: &VM, extended_ty: BytecodeType) -> Option<Extensi

fn lookup_impl_for_ty(vm: &VM, trait_id: TraitId, extended_ty: BytecodeType) -> Option<ImplId> {
for (id, impl_) in vm.program.impls.iter().enumerate() {
match &impl_.trait_ty {
BytecodeType::TraitObject(impl_trait_id, ..) if *impl_trait_id == trait_id => {}
_ => continue,
if impl_.trait_ty.trait_id != trait_id {
continue;
}

if impl_.extended_ty == extended_ty {
Expand All @@ -210,9 +209,8 @@ fn lookup_impl_for_ty(vm: &VM, trait_id: TraitId, extended_ty: BytecodeType) ->

fn lookup_impl_for_item(vm: &VM, trait_id: TraitId, extended_ty: ModuleItem) -> Option<ImplId> {
for (id, impl_) in vm.program.impls.iter().enumerate() {
match &impl_.trait_ty {
BytecodeType::TraitObject(impl_trait_id, ..) if *impl_trait_id == trait_id => {}
_ => continue,
if impl_.trait_ty.trait_id != trait_id {
continue;
}

match impl_.extended_ty {
Expand Down

0 comments on commit 3742770

Please sign in to comment.