mirror of
https://github.com/enso-org/enso.git
synced 2024-11-22 11:52:59 +03:00
Presence of Any disables type checks (#10248)
Fixes #10237 by avoiding creation of `ReadArgumentCheckNode` when the requested type allows `Any`.
This commit is contained in:
parent
46f6b4f698
commit
87864bf564
@ -1,5 +1,7 @@
|
||||
package org.enso.interpreter.test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
@ -267,4 +269,68 @@ public class AutoscopedConstructorTest {
|
||||
e.getMessage().contains("Type_Error"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleAnyCheck() {
|
||||
var code =
|
||||
"""
|
||||
import Standard.Base.Any.Any
|
||||
|
||||
type A
|
||||
Typed x:Any
|
||||
|
||||
t = ..Typed ..My_Other
|
||||
materialize v:A = v
|
||||
|
||||
create = materialize t
|
||||
""";
|
||||
|
||||
var create = ctx.eval("enso", code).invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
|
||||
|
||||
assertEquals("A", create.getMetaObject().getMetaSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleAnyOrACheck() {
|
||||
var code =
|
||||
"""
|
||||
import Standard.Base.Any.Any
|
||||
|
||||
type A
|
||||
Typed (x:Any|A)
|
||||
|
||||
t = ..Typed ..My_Other
|
||||
materialize v:A = v
|
||||
|
||||
create = materialize t
|
||||
""";
|
||||
|
||||
var create = ctx.eval("enso", code).invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
|
||||
|
||||
assertEquals("A", create.getMetaObject().getMetaSimpleName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void intersectionAnyOrACheck() {
|
||||
var code =
|
||||
"""
|
||||
import Standard.Base.Any.Any
|
||||
|
||||
type A
|
||||
Typed (x:Any&A)
|
||||
|
||||
t = ..Typed ..My_Other
|
||||
materialize v:A = v
|
||||
|
||||
create = materialize t
|
||||
""";
|
||||
|
||||
try {
|
||||
var create =
|
||||
ctx.eval("enso", code).invokeMember(MethodNames.Module.EVAL_EXPRESSION, "create");
|
||||
fail("Got value, but expecting an exception: " + create);
|
||||
} catch (PolyglotException ex) {
|
||||
assertThat(ex.getMessage(), containsString("Cannot find constructor ..My_Other among A."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -157,7 +157,8 @@ public abstract class ReadArgumentCheckNode extends Node {
|
||||
};
|
||||
}
|
||||
|
||||
public static ReadArgumentCheckNode build(String comment, Type expectedType) {
|
||||
public static ReadArgumentCheckNode build(EnsoContext ctx, String comment, Type expectedType) {
|
||||
assert ctx.getBuiltins().any() != expectedType : "Don't check for Any: " + expectedType;
|
||||
return ReadArgumentCheckNodeFactory.TypeCheckNodeGen.create(comment, expectedType);
|
||||
}
|
||||
|
||||
@ -423,6 +424,9 @@ public abstract class ReadArgumentCheckNode extends Node {
|
||||
if (v instanceof EnsoMultiValue multi) {
|
||||
return multi.allTypes();
|
||||
}
|
||||
if (v instanceof UnresolvedConstructor) {
|
||||
return null;
|
||||
}
|
||||
if (typeOfNode.execute(v) instanceof Type from) {
|
||||
if (previous != null && previous.length == 1 && previous[0] == from) {
|
||||
return previous;
|
||||
|
@ -752,10 +752,15 @@ class IrToTruffle(
|
||||
t: Expression
|
||||
): ReadArgumentCheckNode = t match {
|
||||
case u: `type`.Set.Union =>
|
||||
ReadArgumentCheckNode.oneOf(
|
||||
comment,
|
||||
u.operands.map(extractAscribedType(comment, _)).asJava
|
||||
)
|
||||
val oneOf = u.operands.map(extractAscribedType(comment, _))
|
||||
if (oneOf.contains(null)) {
|
||||
null
|
||||
} else {
|
||||
ReadArgumentCheckNode.oneOf(
|
||||
comment,
|
||||
oneOf.asJava
|
||||
)
|
||||
}
|
||||
case i: `type`.Set.Intersection =>
|
||||
ReadArgumentCheckNode.allOf(
|
||||
comment,
|
||||
@ -765,6 +770,7 @@ class IrToTruffle(
|
||||
case p: Application.Prefix => extractAscribedType(comment, p.function)
|
||||
case _: Tpe.Function =>
|
||||
ReadArgumentCheckNode.build(
|
||||
context,
|
||||
comment,
|
||||
context.getTopScope().getBuiltins().function()
|
||||
)
|
||||
@ -780,10 +786,12 @@ class IrToTruffle(
|
||||
BindingsMap
|
||||
.Resolution(binding @ BindingsMap.ResolvedType(_, _))
|
||||
) =>
|
||||
ReadArgumentCheckNode.build(
|
||||
comment,
|
||||
asType(binding)
|
||||
)
|
||||
val typeOrAny = asType(binding)
|
||||
if (context.getBuiltins().any() == typeOrAny) {
|
||||
null
|
||||
} else {
|
||||
ReadArgumentCheckNode.build(context, comment, typeOrAny)
|
||||
}
|
||||
case Some(
|
||||
BindingsMap
|
||||
.Resolution(BindingsMap.ResolvedPolyglotSymbol(mod, symbol))
|
||||
|
@ -72,6 +72,16 @@ type Forth
|
||||
Back.from (that:Forth) = Back.Times that.n+1
|
||||
Forth.from (that:Back) = Forth.Times that.n+1
|
||||
|
||||
type Autoscope_Type
|
||||
Raw v
|
||||
Typed v:Any
|
||||
Complex1 v:Autoscope_Type|Any
|
||||
Complex2 v:Any|Autoscope_Type
|
||||
|
||||
f_typed v:Any = Autoscope_Type.Raw v
|
||||
f_complex1 v:Autoscope_Type|Any = Autoscope_Type.Raw v
|
||||
f_complex2 v:Any|Autoscope_Type = Autoscope_Type.Raw v
|
||||
|
||||
foreign js make_str x = """
|
||||
return "js string"
|
||||
|
||||
@ -543,6 +553,70 @@ add_specs suite_builder =
|
||||
|
||||
accept ..Nothing . is_nothing . should_be_true
|
||||
|
||||
group_builder.specify "Autoscope_Type Raw" <|
|
||||
r = ..Raw ..My_Other
|
||||
x = r:Autoscope_Type
|
||||
Meta.type_of x . should_equal Autoscope_Type
|
||||
x.to_text . should_equal "(Raw ..My_Other)"
|
||||
|
||||
group_builder.specify "Autoscope_Type Typed" <|
|
||||
r = ..Typed ..My_Other
|
||||
x = r:Autoscope_Type
|
||||
Meta.type_of x . should_equal Autoscope_Type
|
||||
x.to_text . should_equal "(Typed ..My_Other)"
|
||||
|
||||
group_builder.specify "Autoscope_Type Complex1" <|
|
||||
r = ..Complex1 ..My_Other
|
||||
x = r:Autoscope_Type
|
||||
Meta.type_of x . should_equal Autoscope_Type
|
||||
x.to_text . should_equal "(Complex1 ..My_Other)"
|
||||
|
||||
group_builder.specify "Autoscope_Type Complex2" <|
|
||||
r = ..Complex2 ..My_Other
|
||||
x = r:Autoscope_Type
|
||||
Meta.type_of x . should_equal Autoscope_Type
|
||||
x.to_text . should_equal "(Complex2 ..My_Other)"
|
||||
|
||||
group_builder.specify "Autoscope_Type factory typed" <|
|
||||
x = Autoscope_Type.f_typed ..My_Other
|
||||
Meta.type_of x . should_equal Autoscope_Type
|
||||
x.to_text . should_equal "(Raw ..My_Other)"
|
||||
|
||||
group_builder.specify "Autoscope_Type factory complex1" <|
|
||||
x = Autoscope_Type.f_complex1 ..My_Other
|
||||
Meta.type_of x . should_equal Autoscope_Type
|
||||
x.to_text . should_equal "(Raw ..My_Other)"
|
||||
|
||||
group_builder.specify "Autoscope_Type factory complex2" <|
|
||||
x = Autoscope_Type.f_complex2 ..My_Other
|
||||
Meta.type_of x . should_equal Autoscope_Type
|
||||
x.to_text . should_equal "(Raw ..My_Other)"
|
||||
|
||||
|
||||
confused1 filter =
|
||||
materialize f:Foo = f
|
||||
|
||||
case filter of
|
||||
_:Function -> Panic.catch Any (materialize filter) err->
|
||||
[err, filter]
|
||||
_ -> filter
|
||||
|
||||
group_builder.specify "Order of specializations 1 & 2" <|
|
||||
fn x = x+2
|
||||
|
||||
r1 = confused1 fn
|
||||
r2 = confused1 (..Value 4)
|
||||
r = [r1, r2]
|
||||
r.to_text . should_contain "Foo.Value 4"
|
||||
|
||||
group_builder.specify "Order of specializations 2 & 1" <|
|
||||
fn x = x+2
|
||||
|
||||
r2 = confused1 (..Value 4)
|
||||
r1 = confused1 fn
|
||||
r = [r1, r2]
|
||||
r.to_text . should_contain "Foo.Value 4"
|
||||
|
||||
suite_builder.group "Polyglot Argument" group_builder->
|
||||
f1 (x : DateTimeFormatter) = x.to_text
|
||||
f2 (x : Text | DateTimeFormatter) = case x of
|
||||
|
Loading…
Reference in New Issue
Block a user