Skip to content

Commit

Permalink
sema: fix impl statement handling for structures
Browse files Browse the repository at this point in the history
  • Loading branch information
mertcandav committed Jan 13, 2025
1 parent 0f715e1 commit 23fff30
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 40 deletions.
1 change: 1 addition & 0 deletions std/jule/sema/func.jule
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ struct FuncIns {

caller: builtinCaller
reloaded: bool
checked: bool
}

impl Kind for FuncIns {
Expand Down
57 changes: 17 additions & 40 deletions std/jule/sema/sema.jule
Original file line number Diff line number Diff line change
Expand Up @@ -1960,6 +1960,14 @@ impl sema {
| !self.checkStructImpls(s):
| !self.checkFuncDeclsBy(s.Methods):
}

// Here, we need to dispatch the methods again.
// At this point, all `impl` statements should already be implemented.
// During this process, some instances might have been created without
// having the methods. To prevent this from causing errors,
// the missing methods added with the `impl` statements must be dispatched
// to the instances that have not have these methods.
s.dispatchMethods()
}

// Checks current package file's structure declarations.
Expand Down Expand Up @@ -2233,16 +2241,9 @@ impl sema {
}

fn checkTypeMethod(mut &self, mut &s: &StructIns, mut &f: &Func) {
// Generic instances are checked instantly.
if len(f.Generics) > 0 {
ret
}
mut ins := f.Instances[0]
if len(ins.Scope.Stmts) > 0 {
// Checked
ret
for (_, mut ins) in f.Instances {
self.checkFuncIns(ins)
}
self.checkFuncIns(ins)
}

// Checks environment-dependent parts of structure instance.
Expand Down Expand Up @@ -2400,18 +2401,13 @@ impl sema {
ret
}

// Generic instances are checked instantly.
if len(s.Generics) > 0 {
ret
}

if len(s.Instances) == 0 {
if len(s.Generics) == 0 && len(s.Instances) == 0 {
mut ins := s.instance()
s.appendInstance(ins) // Append instance before precheck.
}

// Precheck is instance is not checked already.
{
if len(s.Generics) == 0 {
mut ins := s.Instances[0]
if !ins.Checked {
ins.Checked = true
Expand All @@ -2438,18 +2434,13 @@ impl sema {
ret
}

// Generic instances are checked instantly.
if len(s.Generics) > 0 {
ret
}

if len(s.Instances) == 0 {
if len(s.Generics) == 0 && len(s.Instances) == 0 {
mut ins := s.instance()
s.appendInstance(ins) // Append instance before precheck.
}

// Precheck is instance is not checked already.
{
if len(s.Generics) == 0 {
mut ins := s.Instances[0]
if !ins.Checked {
ins.Checked = true
Expand Down Expand Up @@ -2492,9 +2483,10 @@ impl sema {
}

fn checkFuncInsCaller(mut &self, mut &f: &FuncIns, mut caller: &token::Token) {
if f.Decl.Binded {
if f.Decl.Binded || f.checked {
ret
}
f.checked = true

mut old := f.Decl.sema.file
defer { f.Decl.sema.setCurrentFile(old) }
Expand All @@ -2521,12 +2513,6 @@ impl sema {
if f.Binded {
ret
}

// Generic instances are checked instantly.
if len(f.Generics) > 0 {
ret
}

for (_, mut ins) in f.Instances {
self.checkFuncIns(ins)
}
Expand Down Expand Up @@ -2569,16 +2555,7 @@ impl sema {
}

fn precheckFunc(mut &self, mut &f: &Func) {
if f.Binded {
ret
}

// Generic instances are checked instantly.
if len(f.Generics) > 0 {
ret
}

if len(f.Instances) == 0 {
if !f.Binded && len(f.Generics) == 0 && len(f.Instances) == 0 {
mut ins := f.instanceForce()
f.Instances = append(f.Instances, ins)
ok := self.reloadFuncInsTypes(ins)
Expand Down
21 changes: 21 additions & 0 deletions std/jule/sema/struct.jule
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,27 @@ struct Struct {
}

impl Struct {
// Dispatches methods to instances if needed.
fn dispatchMethods(mut &self) {
if len(self.Instances) == 0 || len(self.Methods) == 0 {
ret
}
if len(self.Generics) == 0 {
self.Instances[0].Methods = self.Methods
ret
}
for (_, mut ins) in self.Instances {
if len(ins.Methods) != len(self.Methods) {
ins.Methods = make([]&Func, 0, len(self.Methods))
for (_, mut f) in self.Methods {
mut fins := new(Func, *f)
fins.Instances = nil
ins.Methods = append(ins.Methods, fins)
}
}
}
}

fn instance(mut &self): &StructIns {
// Returns already created instance for just one unique combination.
if len(self.Generics) == 0 && len(self.Instances) == 1 {
Expand Down

0 comments on commit 23fff30

Please sign in to comment.