Skip to content

Commit 826c168

Browse files
committed
Merge pull request #14635 from ethereum/new-analysis-remove-polymorphic-instance
Adjust `polymorphicInstance()`
2 parents 058ff1d + c392de0 commit 826c168

10 files changed

+399
-18
lines changed

libsolidity/experimental/analysis/TypeInference.cpp

+7-14
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,7 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition)
216216
subNode->accept(*this);
217217
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get());
218218
solAssert(functionDefinition);
219-
// TODO: need polymorphicInstance?
220-
auto functionType = polymorphicInstance(typeAnnotation(*functionDefinition));
219+
auto functionType = typeAnnotation(*functionDefinition);
221220
if (!functionTypes.emplace(functionDefinition->name(), functionType).second)
222221
m_errorReporter.fatalTypeError(3195_error, functionDefinition->location(), "Function in type class declared multiple times.");
223222
auto typeVars = TypeEnvironmentHelpers{*m_env}.typeVars(functionType);
@@ -481,7 +480,10 @@ experimental::Type TypeInference::handleIdentifierByReferencedDeclaration(langut
481480
else if (dynamic_cast<FunctionDefinition const*>(&_declaration))
482481
return polymorphicInstance(*declarationAnnotation.type);
483482
else if (dynamic_cast<TypeClassDefinition const*>(&_declaration))
484-
return polymorphicInstance(*declarationAnnotation.type);
483+
{
484+
solAssert(TypeEnvironmentHelpers{*m_env}.typeVars(*declarationAnnotation.type).empty());
485+
return *declarationAnnotation.type;
486+
}
485487
else if (dynamic_cast<TypeDefinition const*>(&_declaration))
486488
{
487489
// TODO: can we avoid this?
@@ -1069,18 +1071,9 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysi
10691071
}
10701072
}
10711073

1072-
void TypeInference::unifyGeneralized(Type _type, Type _scheme, std::vector<Type> _monomorphicTypes, langutil::SourceLocation _location)
1073-
{
1074-
solUnimplementedAssert(_monomorphicTypes.empty(), "unsupported");
1075-
Type fresh = m_env->fresh(_scheme);
1076-
unify(_type, fresh, _location);
1077-
}
1078-
1079-
experimental::Type TypeInference::polymorphicInstance(Type _scheme, langutil::SourceLocation _location)
1074+
experimental::Type TypeInference::polymorphicInstance(Type const& _scheme)
10801075
{
1081-
Type result = m_typeSystem.freshTypeVariable({});
1082-
unifyGeneralized(result, _scheme, {}, _location);
1083-
return result;
1076+
return m_env->fresh(_scheme);
10841077
}
10851078

10861079
void TypeInference::unify(Type _a, Type _b, langutil::SourceLocation _location)

libsolidity/experimental/analysis/TypeInference.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ class TypeInference: public ASTConstVisitor
110110
GlobalAnnotation& annotation();
111111

112112
void unify(Type _a, Type _b, langutil::SourceLocation _location = {});
113-
void unifyGeneralized(Type _type, Type _scheme, std::vector<Type> _monomorphicTypes, langutil::SourceLocation _location = {});
114-
Type polymorphicInstance(Type _scheme, langutil::SourceLocation _location = {});
113+
/// Creates a polymorphic instance of a global type scheme
114+
Type polymorphicInstance(Type const& _scheme);
115115
Type memberType(Type _type, std::string _memberName, langutil::SourceLocation _location = {});
116116
enum class ExpressionContext { Term, Type, Sort };
117117
Type handleIdentifierByReferencedDeclaration(langutil::SourceLocation _location, Declaration const& _declaration);

test/libsolidity/syntaxTests/experimental/builtin/builtin_type_definition.sol

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,9 @@ contract C {
8484
// Info 4164: (525-529): Inferred type: word
8585
// Info 4164: (540-553): Inferred type: bool
8686
// Info 4164: (540-550): Inferred type: (bool, word) -> bool
87-
// Info 4164: (540-544): Inferred type: ('cb:type, 'cc:type)
87+
// Info 4164: (540-544): Inferred type: ('bl:type, 'bm:type)
8888
// Info 4164: (551-552): Inferred type: (bool, word)
8989
// Info 4164: (563-577): Inferred type: word
9090
// Info 4164: (563-574): Inferred type: (bool, word) -> word
91-
// Info 4164: (563-567): Inferred type: ('ci:type, 'cj:type)
91+
// Info 4164: (563-567): Inferred type: ('bq:type, 'br:type)
9292
// Info 4164: (575-576): Inferred type: (bool, word)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pragma experimental solidity;
2+
3+
type T;
4+
type U;
5+
6+
function f(x: T, y: U) {}
7+
8+
function run(a: U, b: T) {
9+
f(a, b);
10+
}
11+
// ====
12+
// EVMVersion: >=constantinople
13+
// ----
14+
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
15+
// TypeError 8456: (106-113): Cannot unify T and U.
16+
// TypeError 8456: (106-113): Cannot unify U and T.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
pragma experimental solidity;
2+
3+
type T;
4+
type U(A);
5+
6+
function f(x, y: X, z: U(Y)) {}
7+
8+
function run(a: T, b: U(T), c: U(U(T))) {
9+
f(a, a, b);
10+
f(b, b, c);
11+
}
12+
// ====
13+
// EVMVersion: >=constantinople
14+
// compileViaYul: true
15+
// ----
16+
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
17+
// Info 4164: (31-38): Inferred type: T
18+
// Info 4164: (39-49): Inferred type: tfun('u:type, U('u:type))
19+
// Info 4164: (45-48): Inferred type: 't:type
20+
// Info 4164: (46-47): Inferred type: 't:type
21+
// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('ba:type)) -> ()
22+
// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('ba:type))
23+
// Info 4164: (62-63): Inferred type: 'x:type
24+
// Info 4164: (65-69): Inferred type: 'y:type
25+
// Info 4164: (68-69): Inferred type: 'y:type
26+
// Info 4164: (71-78): Inferred type: U('ba:type)
27+
// Info 4164: (74-78): Inferred type: U('ba:type)
28+
// Info 4164: (74-75): Inferred type: tfun('ba:type, U('ba:type))
29+
// Info 4164: (76-77): Inferred type: 'ba:type
30+
// Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> ()
31+
// Info 4164: (96-123): Inferred type: (T, U(T), U(U(T)))
32+
// Info 4164: (97-101): Inferred type: T
33+
// Info 4164: (100-101): Inferred type: T
34+
// Info 4164: (103-110): Inferred type: U(T)
35+
// Info 4164: (106-110): Inferred type: U(T)
36+
// Info 4164: (106-107): Inferred type: tfun(T, U(T))
37+
// Info 4164: (108-109): Inferred type: T
38+
// Info 4164: (112-122): Inferred type: U(U(T))
39+
// Info 4164: (115-122): Inferred type: U(U(T))
40+
// Info 4164: (115-116): Inferred type: tfun(U(T), U(U(T)))
41+
// Info 4164: (117-121): Inferred type: U(T)
42+
// Info 4164: (117-118): Inferred type: tfun(T, U(T))
43+
// Info 4164: (119-120): Inferred type: T
44+
// Info 4164: (130-140): Inferred type: ()
45+
// Info 4164: (130-131): Inferred type: (T, T, U(T)) -> ()
46+
// Info 4164: (132-133): Inferred type: T
47+
// Info 4164: (135-136): Inferred type: T
48+
// Info 4164: (138-139): Inferred type: U(T)
49+
// Info 4164: (146-156): Inferred type: ()
50+
// Info 4164: (146-147): Inferred type: (U(T), U(T), U(U(T))) -> ()
51+
// Info 4164: (148-149): Inferred type: U(T)
52+
// Info 4164: (151-152): Inferred type: U(T)
53+
// Info 4164: (154-155): Inferred type: U(U(T))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
pragma experimental solidity;
2+
3+
type T;
4+
type U;
5+
6+
function f(x) {}
7+
8+
function run(a: T, b: U) {
9+
// NOTE: The type of f is polymorphic but the inferred type of g is not - this would be
10+
// let-polymorphism, which we decided not to support.
11+
let g = f;
12+
g(a);
13+
g(b);
14+
}
15+
// ====
16+
// EVMVersion: >=constantinople
17+
// ----
18+
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
19+
// TypeError 8456: (272-276): Cannot unify T and U.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
pragma experimental solidity;
2+
3+
type T(A);
4+
type U;
5+
type V;
6+
7+
function f(x: T(U)) {}
8+
9+
function run(a: T(V)) {
10+
f(a);
11+
}
12+
// ====
13+
// EVMVersion: >=constantinople
14+
// ----
15+
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
16+
// TypeError 8456: (111-115): Cannot unify U and V.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
pragma experimental solidity;
2+
3+
type T(P, Q, R);
4+
type U;
5+
type V;
6+
7+
class Self: C {}
8+
class Self: D {}
9+
10+
function run() {
11+
let x: T(U, X, Z: C);
12+
let y: T(V, Y, Z: D);
13+
}
14+
// ====
15+
// EVMVersion: >=constantinople
16+
// compileViaYul: true
17+
// ----
18+
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
19+
// Info 4164: (31-47): Inferred type: tfun(('ba:type, 'bb:type, 'bc:type), T('ba:type, 'bb:type, 'bc:type))
20+
// Info 4164: (37-46): Inferred type: ('x:type, 'y:type, 'z:type)
21+
// Info 4164: (38-39): Inferred type: 'x:type
22+
// Info 4164: (41-42): Inferred type: 'y:type
23+
// Info 4164: (44-45): Inferred type: 'z:type
24+
// Info 4164: (48-55): Inferred type: U
25+
// Info 4164: (56-63): Inferred type: V
26+
// Info 4164: (65-81): Inferred type: C
27+
// Info 4164: (71-75): Inferred type: 'be:(type, C)
28+
// Info 4164: (82-98): Inferred type: D
29+
// Info 4164: (88-92): Inferred type: 'bg:(type, D)
30+
// Info 4164: (100-170): Inferred type: () -> ()
31+
// Info 4164: (112-114): Inferred type: ()
32+
// Info 4164: (125-141): Inferred type: T(U, 'bm:type, 'bo:(type, C))
33+
// Info 4164: (128-141): Inferred type: T(U, 'bm:type, 'bo:(type, C))
34+
// Info 4164: (128-129): Inferred type: tfun((U, 'bm:type, 'bo:(type, C)), T(U, 'bm:type, 'bo:(type, C)))
35+
// Info 4164: (130-131): Inferred type: U
36+
// Info 4164: (133-134): Inferred type: 'bm:type
37+
// Info 4164: (136-140): Inferred type: 'bo:(type, C)
38+
// Info 4164: (136-137): Inferred type: 'bo:(type, C)
39+
// Info 4164: (139-140): Inferred type: 'bo:(type, C)
40+
// Info 4164: (151-167): Inferred type: T(V, 'bt:type, 'bv:(type, D))
41+
// Info 4164: (154-167): Inferred type: T(V, 'bt:type, 'bv:(type, D))
42+
// Info 4164: (154-155): Inferred type: tfun((V, 'bt:type, 'bv:(type, D)), T(V, 'bt:type, 'bv:(type, D)))
43+
// Info 4164: (156-157): Inferred type: V
44+
// Info 4164: (159-160): Inferred type: 'bt:type
45+
// Info 4164: (162-166): Inferred type: 'bv:(type, D)
46+
// Info 4164: (162-163): Inferred type: 'bv:(type, D)
47+
// Info 4164: (165-166): Inferred type: 'bv:(type, D)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
pragma experimental solidity;
2+
3+
type uint;
4+
type string;
5+
6+
type T(A);
7+
type U(B) = T(B);
8+
9+
function fun() {
10+
let w: U(uint);
11+
let v: T(uint);
12+
U.rep(w);
13+
U.abs(v);
14+
15+
let s: U(string);
16+
let t: T(string);
17+
U.rep(s);
18+
U.abs(t);
19+
}
20+
// ====
21+
// EVMVersion: >=constantinople
22+
// compileViaYul: true
23+
// ----
24+
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
25+
// Info 4164: (31-41): Inferred type: uint
26+
// Info 4164: (42-54): Inferred type: string
27+
// Info 4164: (56-66): Inferred type: tfun('v:type, T('v:type))
28+
// Info 4164: (62-65): Inferred type: 'u:type
29+
// Info 4164: (63-64): Inferred type: 'u:type
30+
// Info 4164: (67-84): Inferred type: tfun('x:type, U('x:type))
31+
// Info 4164: (73-76): Inferred type: 'w:type
32+
// Info 4164: (74-75): Inferred type: 'w:type
33+
// Info 4164: (79-83): Inferred type: T('w:type)
34+
// Info 4164: (79-80): Inferred type: tfun('w:type, T('w:type))
35+
// Info 4164: (81-82): Inferred type: 'w:type
36+
// Info 4164: (86-245): Inferred type: () -> ()
37+
// Info 4164: (98-100): Inferred type: ()
38+
// Info 4164: (111-121): Inferred type: U(uint)
39+
// Info 4164: (114-121): Inferred type: U(uint)
40+
// Info 4164: (114-115): Inferred type: tfun(uint, U(uint))
41+
// Info 4164: (116-120): Inferred type: uint
42+
// Info 4164: (131-141): Inferred type: T(uint)
43+
// Info 4164: (134-141): Inferred type: T(uint)
44+
// Info 4164: (134-135): Inferred type: tfun(uint, T(uint))
45+
// Info 4164: (136-140): Inferred type: uint
46+
// Info 4164: (147-155): Inferred type: T('bi:type)
47+
// Info 4164: (147-152): Inferred type: U(uint) -> T('bi:type)
48+
// Info 4164: (147-148): Inferred type: U('bg:type)
49+
// Info 4164: (153-154): Inferred type: U(uint)
50+
// Info 4164: (161-169): Inferred type: U('bm:type)
51+
// Info 4164: (161-166): Inferred type: T(uint) -> U('bm:type)
52+
// Info 4164: (161-162): Inferred type: U('bk:type)
53+
// Info 4164: (167-168): Inferred type: T(uint)
54+
// Info 4164: (180-192): Inferred type: U(string)
55+
// Info 4164: (183-192): Inferred type: U(string)
56+
// Info 4164: (183-184): Inferred type: tfun(string, U(string))
57+
// Info 4164: (185-191): Inferred type: string
58+
// Info 4164: (202-214): Inferred type: T(string)
59+
// Info 4164: (205-214): Inferred type: T(string)
60+
// Info 4164: (205-206): Inferred type: tfun(string, T(string))
61+
// Info 4164: (207-213): Inferred type: string
62+
// Info 4164: (220-228): Inferred type: T('bu:type)
63+
// Info 4164: (220-225): Inferred type: U(string) -> T('bu:type)
64+
// Info 4164: (220-221): Inferred type: U('bs:type)
65+
// Info 4164: (226-227): Inferred type: U(string)
66+
// Info 4164: (234-242): Inferred type: U('by:type)
67+
// Info 4164: (234-239): Inferred type: T(string) -> U('by:type)
68+
// Info 4164: (234-235): Inferred type: U('bw:type)
69+
// Info 4164: (240-241): Inferred type: T(string)

0 commit comments

Comments
 (0)