Skip to content

Commit 5688476

Browse files
authored
Merge pull request #278 from Pivot-Studio/feat/trait_bound_multi
trait bound multi
2 parents f6d2c41 + ad9375b commit 5688476

File tree

20 files changed

+528
-304
lines changed

20 files changed

+528
-304
lines changed

Cargo.lock

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pl_linker = { path = "./pl_linker", optional = true }
1313
immix = { path = "./immix", optional = true, features = ["llvm_gc_plugin", "llvm_stackmap"] }
1414
vm = { path = "./vm", optional = true, features = ["jit"] }
1515
indexmap = "1.9"
16+
linked-hash-map = "0.5.6"
1617
lazy_static = "1.4"
1718
paste = "1.0"
1819
internal_macro = { path = "./internal_macro", default-features = false }

src/ast/builder/llvmbuilder.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
819819
let mut m = vec![];
820820
ctx.run_in_type_mod(x, |ctx, x| {
821821
m = x
822-
.ordered_fields
822+
.get_all_field()
823823
.iter()
824824
.map(|v| {
825825
let offset = td.offset_of_element(&sttp, v.index).unwrap() * 8;
@@ -957,9 +957,8 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
957957
ctx.run_in_type_mod(pltp, |ctx, pltp| {
958958
st.set_body(
959959
&pltp
960-
.ordered_fields
961-
.clone()
962-
.into_iter()
960+
.get_all_field()
961+
.iter()
963962
.map(|order_field| {
964963
self.get_basic_type_op(
965964
&order_field
@@ -1195,10 +1194,11 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
11951194
self.context.opaque_struct_type(name);
11961195
}
11971196

1198-
fn add_body_to_struct_type(&self, name: &str, order_fields: &[Field], ctx: &mut Ctx<'a>) {
1197+
fn add_body_to_struct_type(&self, name: &str, sttype: &STType, ctx: &mut Ctx<'a>) {
11991198
let st = self.module.get_struct_type(name).unwrap();
12001199
st.set_body(
1201-
&order_fields
1200+
&sttype
1201+
.get_all_field()
12021202
.iter()
12031203
.map(|order_field| {
12041204
self.get_basic_type_op(

src/ast/builder/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use super::{
1414
ctx::Ctx,
1515
diag::PLDiag,
1616
node::{types::TypedIdentifierNode, TypeNodeEnum},
17-
pltype::{FNValue, Field, PLType, PriType, STType},
17+
pltype::{FNValue, PLType, PriType, STType},
1818
range::{Pos, Range},
1919
};
2020

@@ -119,7 +119,7 @@ pub trait IRBuilder<'a, 'ctx> {
119119
) -> ValueHandle;
120120
fn build_unconditional_branch(&self, bb: BlockHandle);
121121
fn position_at_end_block(&self, block: BlockHandle);
122-
fn add_body_to_struct_type(&self, name: &str, order_fields: &[Field], ctx: &mut Ctx<'a>);
122+
fn add_body_to_struct_type(&self, name: &str, sttype: &STType, ctx: &mut Ctx<'a>);
123123
fn get_or_insert_fn_handle(&self, pltp: &FNValue, ctx: &mut Ctx<'a>) -> ValueHandle;
124124
fn get_or_add_global(
125125
&self,

src/ast/builder/no_op_builder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for NoOpBuilder<'a, 'ctx> {
201201
fn add_body_to_struct_type(
202202
&self,
203203
_name: &str,
204-
_order_fields: &[crate::ast::pltype::Field],
204+
_sttype: &STType,
205205
_ctx: &mut crate::ast::ctx::Ctx<'a>,
206206
) {
207207
}

src/ast/ctx.rs

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,8 +274,8 @@ impl<'a, 'ctx> Ctx<'a> {
274274
));
275275
}
276276
let trait_handle = builder.alloc("tmp_traitv", &trait_pltype.borrow(), self, None);
277-
for (name, f) in &t.fields {
278-
let mthd = st.find_method(self, name).unwrap();
277+
for f in t.list_trait_fields().iter() {
278+
let mthd = st.find_method(self, &f.name).unwrap();
279279
let fnhandle = builder.get_or_insert_fn_handle(&mthd, self);
280280
let targetftp = f.typenode.get_type(self, builder).unwrap();
281281
let casted = builder.bitcast(self, fnhandle, &targetftp.borrow(), "fncast_tmp");
@@ -1012,9 +1012,12 @@ impl<'a, 'ctx> Ctx<'a> {
10121012
need_up_cast: false,
10131013
};
10141014
}
1015-
} else if !self
1016-
.eq(lg.trait_impl.as_ref().unwrap().clone(), r.clone())
1017-
.eq
1015+
} else if lg
1016+
.trait_impl
1017+
.as_ref()
1018+
.unwrap()
1019+
.iter()
1020+
.any(|lt| !self.eq(lt.clone(), r.clone()).eq)
10181021
{
10191022
return EqRes {
10201023
eq: false,
@@ -1031,6 +1034,12 @@ impl<'a, 'ctx> Ctx<'a> {
10311034
unreachable!()
10321035
}
10331036
if l != r {
1037+
if matches!(&*l.borrow(), PLType::Union(_)) {
1038+
return EqRes {
1039+
eq: true,
1040+
need_up_cast: true,
1041+
};
1042+
}
10341043
let trait_pltype = l;
10351044
let st_pltype = self.auto_deref_tp(r);
10361045
if let (PLType::Trait(t), PLType::Struct(st)) =
@@ -1040,11 +1049,6 @@ impl<'a, 'ctx> Ctx<'a> {
10401049
eq: st.implements_trait(t, &self.plmod),
10411050
need_up_cast: true,
10421051
};
1043-
} else if let PLType::Union(_) = &*trait_pltype.borrow() {
1044-
return EqRes {
1045-
eq: true,
1046-
need_up_cast: true,
1047-
};
10481052
}
10491053
return EqRes {
10501054
eq: false,

src/ast/diag.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,8 @@ define_error!(
118118
UNION_DOES_NOT_CONTAIN_TYPE = "union does not contain type",
119119
INVALID_IS_EXPR = "invalid `is` expression",
120120
INVALID_CAST = "invalid cast",
121-
METHOD_NOT_FOUND = "method not found"
121+
METHOD_NOT_FOUND = "method not found",
122+
DERIVE_TRAIT_NOT_IMPL = "derive trait not impl"
122123
);
123124
macro_rules! define_warn {
124125
($(

src/ast/fmt.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ impl FmtBuilder {
629629
self.token("trait");
630630
self.space();
631631
self.token(node.id.name.as_str());
632+
node.derives.format(self);
632633
self.space();
633634
self.l_brace();
634635
self.enter();
@@ -687,13 +688,19 @@ impl FmtBuilder {
687688
pub fn parse_trait_bound_node(&mut self, node: &TraitBoundNode) {
688689
node.generic.format(self);
689690
if let Some(impl_trait) = &node.impl_trait {
690-
self.token(":");
691-
self.space();
692691
impl_trait.format(self);
693692
}
694693
}
695694
pub fn parse_multi_trait_node(&mut self, node: &MultiTraitNode) {
696-
node.traits.format(self)
695+
if !node.traits.is_empty() {
696+
self.colon();
697+
self.space();
698+
node.traits[0..node.traits.len() - 1].iter().for_each(|d| {
699+
d.format(self);
700+
self.token("+");
701+
});
702+
node.traits.last().unwrap().format(self);
703+
}
697704
}
698705
pub fn parse_union_def_node(&mut self, node: &UnionDefNode) {
699706
self.prefix();

0 commit comments

Comments
 (0)