Skip to content

Commit 4cfe9f6

Browse files
committed
Use Memo<Boolean> for foundDeclaringModule instead of additional wrapper class
1 parent 6b515da commit 4cfe9f6

File tree

4 files changed

+27
-80
lines changed

4 files changed

+27
-80
lines changed

doc/contributor/refinements.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ R1 -> A -> B -> R2 -> D -> E -> C -> ...
9494
The `super` lookup [works in two modes](https://bugs.ruby-lang.org/issues/16977):
9595

9696
1. If `super` is called from a method is directly in R, then we should search in `C` ancestors and ignore other active refinements.
97-
2. If `super` is called from a method placed in a module which included to R, then we should search overall active refinements (as we do for a regular lookup).
97+
2. If `super` is called from a method placed in a module which included to R, then we should search over all active refinements (as we do for a regular lookup).
9898

9999
Additionally, `super` has access to the caller active refinements, so we use `InterlaMethod#activeRefinements` to keep and re-use necessary refinements.
100100

spec/ruby/core/module/refine_spec.rb

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -841,7 +841,7 @@ def bar
841841
using refinement
842842
-> {
843843
refined_class.new.foo
844-
}.should raise_error(NameError)
844+
}.should raise_error(NameError) { |e| e.name.should == :bar }
845845
end
846846
end
847847

@@ -861,22 +861,22 @@ def foo
861861
end
862862
end
863863

864-
refinement = Module.new do
864+
refinement_a = Module.new do
865865
refine refined_class do
866866
include a
867867
end
868868
end
869869

870-
refinement1 = Module.new do
870+
refinement_b = Module.new do
871871
refine refined_class do
872872
include b
873873
end
874874
end
875875

876876
result = nil
877877
Module.new do
878-
using refinement
879-
using refinement1
878+
using refinement_a
879+
using refinement_b
880880
result = refined_class.new.foo
881881
end
882882

@@ -906,7 +906,7 @@ def foo
906906
end
907907
end
908908

909-
refinement1 = Module.new do
909+
refinement_a_b = Module.new do
910910
refine refined_class do
911911
include a
912912
include b
@@ -916,7 +916,7 @@ def foo
916916
result = nil
917917
Module.new do
918918
using refinement
919-
using refinement1
919+
using refinement_a_b
920920
result = refined_class.new.foo
921921
end
922922

src/main/java/org/truffleruby/core/module/ModuleOperations.java

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
import org.truffleruby.Layouts;
1919
import org.truffleruby.RubyContext;
20+
import org.truffleruby.collections.Memo;
2021
import org.truffleruby.core.string.StringUtils;
2122
import org.truffleruby.language.LexicalScope;
2223
import org.truffleruby.language.RubyConstant;
@@ -501,74 +502,76 @@ public static MethodLookupResult lookupSuperMethod(InternalMethod currentMethod,
501502

502503
assert RubyGuards.isRubyModule(objectMetaClass);
503504
final String name = currentMethod.getSharedMethodInfo().getName(); // use the original name
505+
Memo<Boolean> foundDeclaringModule = new Memo<>(false);
504506
return lookupSuperMethod(
505507
currentMethod.getDeclaringModule(),
506-
new SuperMethodLookup(null, false, null),
508+
null,
507509
name,
508510
objectMetaClass,
509-
declarationContext).getResult();
511+
foundDeclaringModule,
512+
declarationContext);
510513
}
511514

512515

513516
@TruffleBoundary
514-
private static SuperMethodLookup lookupSuperMethod(DynamicObject declaringModule, SuperMethodLookup lookup,
515-
String name, DynamicObject objectMetaClass, DeclarationContext declarationContext) {
517+
private static MethodLookupResult lookupSuperMethod(DynamicObject declaringModule, DynamicObject lookupTo,
518+
String name, DynamicObject objectMetaClass, Memo<Boolean> foundDeclaringModule,
519+
DeclarationContext declarationContext) {
516520
assert RubyGuards.isRubyModule(declaringModule);
517521
assert RubyGuards.isRubyModule(objectMetaClass);
518522

519523
final ArrayList<Assumption> assumptions = new ArrayList<>();
520-
final DynamicObject lookupTo = lookup.getLookupTo();
521524
final boolean isRefinedMethod = Layouts.MODULE.getFields(declaringModule).isRefinement();
522525

523526
for (DynamicObject ancestor : Layouts.MODULE.getFields(objectMetaClass).ancestors()) {
524527
if (ancestor == lookupTo) {
525-
return lookup.withResult(new MethodLookupResult(null, toArray(assumptions)));
528+
return new MethodLookupResult(null, toArray(assumptions));
526529
}
527530

528531
final DynamicObject[] refinements = getRefinementsFor(declarationContext, ancestor);
529532

530533
if (refinements != null) {
531534
for (DynamicObject refinement : refinements) {
532-
lookup = lookupSuperMethod(
535+
final MethodLookupResult superMethodInRefinement = lookupSuperMethod(
533536
declaringModule,
534-
lookup.withLookupTo(ancestor),
537+
ancestor,
535538
name,
536539
refinement,
540+
foundDeclaringModule,
537541
null);
538-
final MethodLookupResult superMethodInRefinement = lookup.getResult();
539542
for (Assumption assumption : superMethodInRefinement.getAssumptions()) {
540543
assumptions.add(assumption);
541544
}
542545
if (superMethodInRefinement.isDefined()) {
543546
InternalMethod method = superMethodInRefinement.getMethod();
544-
return lookup.withResult(new MethodLookupResult(
547+
return new MethodLookupResult(
545548
rememberUsedRefinements(method, declarationContext),
546-
toArray(assumptions)));
549+
toArray(assumptions));
547550
}
548-
if (lookup.getFoundDeclaringModule() && isRefinedMethod) {
551+
if (foundDeclaringModule.get() && isRefinedMethod) {
549552
// if method is defined in refinement module (R)
550553
// we should lookup only in this active refinement and skip other
551554
break;
552555
}
553556
}
554557
}
555558

556-
if (!lookup.getFoundDeclaringModule()) {
559+
if (!foundDeclaringModule.get()) {
557560
if (ancestor == declaringModule) {
558-
lookup = lookup.withFoundDeclaringModule(true);
561+
foundDeclaringModule.set(true);
559562
}
560563
} else {
561564
final ModuleFields fields = Layouts.MODULE.getFields(ancestor);
562565
assumptions.add(fields.getMethodsUnmodifiedAssumption());
563566
final InternalMethod method = fields.getMethod(name);
564567
if (method != null) {
565-
return lookup.withResult(new MethodLookupResult(method, toArray(assumptions)));
568+
return new MethodLookupResult(method, toArray(assumptions));
566569
}
567570
}
568571
}
569572

570573
// Nothing found
571-
return lookup.withResult(new MethodLookupResult(null, toArray(assumptions)));
574+
return new MethodLookupResult(null, toArray(assumptions));
572575
}
573576

574577
private static InternalMethod rememberUsedRefinements(InternalMethod method,

src/main/java/org/truffleruby/core/module/SuperMethodLookup.java

Lines changed: 0 additions & 56 deletions
This file was deleted.

0 commit comments

Comments
 (0)