Skip to content

Commit 71c0c68

Browse files
committed
Remove the constant if an autoload fails
* Previously it would be undefined but this behavior was changed in 3.1: https://bugs.ruby-lang.org/issues/15790
1 parent f94c490 commit 71c0c68

File tree

7 files changed

+20
-68
lines changed

7 files changed

+20
-68
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public ConstantLookupResult(RubyConstant constant, Assumption... assumptions) {
2929
}
3030

3131
public boolean isFound() {
32-
return constant != null && !constant.isUndefined();
32+
return constant != null;
3333
}
3434

3535
public boolean isDeprecated() {

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

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -716,15 +716,11 @@ public void deprecateConstant(RubyContext context, Node currentNode, String name
716716
}
717717

718718
@TruffleBoundary
719-
public boolean undefineConstantIfStillAutoload(RubyConstant autoloadConstant) {
719+
public boolean removeConstantIfStillAutoload(RubyConstant autoloadConstant) {
720720
final ConstantEntry constantEntry = constants.get(autoloadConstant.getName());
721721
final boolean replace = constantEntry != null && constantEntry.getConstant() == autoloadConstant;
722-
if (replace &&
723-
constants.replace(
724-
autoloadConstant.getName(),
725-
constantEntry,
726-
new ConstantEntry(autoloadConstant.undefined()))) {
727-
constantEntry.invalidate("undefine if still autoload", rubyModule, autoloadConstant.getName());
722+
if (replace && constants.remove(autoloadConstant.getName(), constantEntry)) {
723+
constantEntry.invalidate("remove if still autoload", rubyModule, autoloadConstant.getName());
728724
return true;
729725
} else {
730726
return false;

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,7 @@ protected Object removeConstant(RubyModule module, String name) {
21962196
getContext(),
21972197
coreExceptions().nameErrorConstantNotDefined(module, name, this));
21982198
} else {
2199-
if (oldConstant.isAutoload() || oldConstant.isUndefined()) {
2199+
if (oldConstant.isAutoload()) {
22002200
return nil;
22012201
} else {
22022202
return oldConstant.getValue();

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,9 +114,8 @@ public static Iterable<Entry<String, ConstantEntry>> getAllConstants(RubyModule
114114
return constants.entrySet();
115115
}
116116

117-
/** NOTE: This method returns false for an undefined RubyConstant */
118117
public static boolean isConstantDefined(RubyConstant constant) {
119-
return constant != null && !constant.isUndefined() &&
118+
return constant != null &&
120119
!(constant.isAutoload() && constant.getAutoloadConstant().isAutoloadingThreadAndUnset());
121120
}
122121

src/main/java/org/truffleruby/language/RubyConstant.java

Lines changed: 2 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,6 @@ public class RubyConstant implements ObjectGraphNode {
3131
private final boolean isDeprecated;
3232

3333
private final AutoloadConstant autoloadConstant;
34-
/** A autoload constant can become "undefined" after the autoload loads the file but the constant is not defined by
35-
* the file */
36-
private final boolean undefined;
3734

3835
private final SourceSection sourceSection;
3936

@@ -45,41 +42,18 @@ public RubyConstant(
4542
AutoloadConstant autoloadConstant,
4643
boolean isDeprecated,
4744
SourceSection sourceSection) {
48-
this(
49-
declaringModule,
50-
name,
51-
value,
52-
isPrivate,
53-
autoloadConstant,
54-
false,
55-
isDeprecated,
56-
sourceSection);
57-
}
58-
59-
private RubyConstant(
60-
RubyModule declaringModule,
61-
String name,
62-
Object value,
63-
boolean isPrivate,
64-
AutoloadConstant autoloadConstant,
65-
boolean undefined,
66-
boolean isDeprecated,
67-
SourceSection sourceSection) {
68-
assert !undefined || autoloadConstant == null : "undefined and autoload are exclusive";
69-
7045
this.declaringModule = declaringModule;
7146
this.name = name;
7247
this.value = value;
7348
this.isPrivate = isPrivate;
7449
this.isDeprecated = isDeprecated;
7550
this.autoloadConstant = autoloadConstant;
76-
this.undefined = undefined;
7751
this.sourceSection = sourceSection;
7852
}
7953

8054
public RubyConstant copy(RubyModule declaringModule) {
8155
assert !isAutoload();
82-
return new RubyConstant(declaringModule, name, value, isPrivate, null, undefined, isDeprecated, sourceSection);
56+
return new RubyConstant(declaringModule, name, value, isPrivate, null, isDeprecated, sourceSection);
8357
}
8458

8559
public RubyModule getDeclaringModule() {
@@ -91,7 +65,7 @@ public String getName() {
9165
}
9266

9367
public boolean hasValue() {
94-
return !isAutoload() && !undefined;
68+
return !isAutoload();
9569
}
9670

9771
public Object getValue() {
@@ -121,7 +95,6 @@ public RubyConstant withPrivate(boolean isPrivate) {
12195
value,
12296
isPrivate,
12397
autoloadConstant,
124-
undefined,
12598
isDeprecated,
12699
sourceSection);
127100
}
@@ -137,17 +110,11 @@ public RubyConstant withDeprecated() {
137110
value,
138111
isPrivate,
139112
autoloadConstant,
140-
undefined,
141113
true,
142114
sourceSection);
143115
}
144116
}
145117

146-
public RubyConstant undefined() {
147-
assert isAutoload();
148-
return new RubyConstant(declaringModule, name, null, isPrivate, null, true, isDeprecated, sourceSection);
149-
}
150-
151118
@TruffleBoundary
152119
public boolean isVisibleTo(RubyContext context, LexicalScope lexicalScope, RubyModule module) {
153120
assert lexicalScope == null || lexicalScope.getLiveModule() == module;
@@ -183,10 +150,6 @@ public boolean isVisibleTo(RubyContext context, LexicalScope lexicalScope, RubyM
183150
return false;
184151
}
185152

186-
public boolean isUndefined() {
187-
return undefined;
188-
}
189-
190153
public boolean isAutoload() {
191154
return autoloadConstant != null;
192155
}

src/main/java/org/truffleruby/language/constants/GetConstantNode.java

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -163,20 +163,18 @@ public static void autoloadConstantStop(RubyConstant autoloadConstant) {
163163

164164
/** Subset of {@link #autoloadResolveConstant} which does not try to resolve the constant. */
165165
@TruffleBoundary
166-
public static boolean autoloadUndefineConstantIfStillAutoload(RubyConstant autoloadConstant) {
166+
public static boolean autoloadRemoveConstantIfStillAutoload(RubyConstant autoloadConstant) {
167167
final RubyModule autoloadConstantModule = autoloadConstant.getDeclaringModule();
168168
final ModuleFields fields = autoloadConstantModule.fields;
169-
return fields.undefineConstantIfStillAutoload(autoloadConstant);
169+
return fields.removeConstantIfStillAutoload(autoloadConstant);
170170
}
171171

172172
@TruffleBoundary
173-
public static void logAutoloadResult(RubyContext context, RubyConstant constant, boolean undefined) {
173+
public static void logAutoloadResult(RubyContext context, RubyConstant constant, boolean removed) {
174174
if (context.getOptions().LOG_AUTOLOAD) {
175175
final SourceSection section = context.getCallStack().getTopMostUserSourceSection();
176176
final String message = context.fileLine(section) + ": " + constant + " " +
177-
(undefined
178-
? "was marked as undefined as it was not assigned in "
179-
: "was successfully autoloaded from ") +
177+
(removed ? "was removed as it was not assigned in " : "was successfully autoloaded from ") +
180178
constant.getAutoloadConstant().getAutoloadPath();
181179
RubyLanguage.LOGGER.info(message);
182180
}
@@ -197,19 +195,19 @@ public Object autoloadResolveConstant(LexicalScope lexicalScope, RubyModule modu
197195
// all is good, just return that constant
198196
logAutoloadResult(getContext(), autoloadConstant, false);
199197
} else {
200-
// If the autoload constant was not set in the ancestors, undefine the constant
201-
boolean undefined = fields.undefineConstantIfStillAutoload(autoloadConstant);
202-
logAutoloadResult(getContext(), autoloadConstant, undefined);
198+
// If the autoload constant was not set in the ancestors, remove the constant
199+
boolean removed = fields.removeConstantIfStillAutoload(autoloadConstant);
200+
logAutoloadResult(getContext(), autoloadConstant, removed);
203201

204-
// redo lookup, to consider the undefined constant
202+
// redo lookup, to consider the removed constant
205203
resolvedConstant = lookupConstantNode.lookupConstant(lexicalScope, module, name, true);
206204
}
207205

208206
return executeGetConstant(lexicalScope, module, name, resolvedConstant, lookupConstantNode, callConstMissing);
209207
}
210208

211209
@Specialization(
212-
guards = { "isNullOrUndefined(constant)", "guardName(node, name, cachedName, sameNameProfile)" },
210+
guards = { "constant == null", "guardName(node, name, cachedName, sameNameProfile)" },
213211
limit = "getCacheLimit()")
214212
protected static Object missingConstantCached(
215213
LexicalScope lexicalScope,
@@ -226,7 +224,7 @@ protected static Object missingConstantCached(
226224
return doMissingConstant(module, name, symbolName, callConstMissing, constMissingNode.get(node));
227225
}
228226

229-
@Specialization(guards = "isNullOrUndefined(constant)")
227+
@Specialization(guards = "constant == null")
230228
protected Object missingConstantUncached(
231229
LexicalScope lexicalScope,
232230
RubyModule module,
@@ -248,10 +246,6 @@ private static Object doMissingConstant(RubyModule module, String name, RubySymb
248246
}
249247
}
250248

251-
protected boolean isNullOrUndefined(Object constant) {
252-
return constant == null || ((RubyConstant) constant).isUndefined();
253-
}
254-
255249
@SuppressFBWarnings("ES")
256250
protected boolean guardName(Node node, String name, String cachedName, InlinedConditionProfile sameNameProfile) {
257251
// This is likely as for literal constant lookup the name does not change and Symbols

src/main/java/org/truffleruby/language/loader/RequireNode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ private boolean requireConsideringAutoload(String feature, String expandedPath,
133133
constant.getAutoloadConstant().publish(getContext(), constant);
134134
}
135135

136-
final boolean undefined = GetConstantNode.autoloadUndefineConstantIfStillAutoload(constant);
137-
GetConstantNode.logAutoloadResult(getContext(), constant, undefined);
136+
final boolean removed = GetConstantNode.autoloadRemoveConstantIfStillAutoload(constant);
137+
GetConstantNode.logAutoloadResult(getContext(), constant, removed);
138138
GetConstantNode.autoloadConstantStop(constant);
139139
featureLoader.removeAutoload(constant);
140140
}

0 commit comments

Comments
 (0)