Skip to content

Commit

Permalink
Merge pull request #14635 from ethereum/new-analysis-remove-polymorph…
Browse files Browse the repository at this point in the history
…ic-instance

Adjust `polymorphicInstance()`
  • Loading branch information
cameel committed Dec 8, 2023
2 parents 058ff1d + c392de0 commit 826c168
Show file tree
Hide file tree
Showing 10 changed files with 399 additions and 18 deletions.
21 changes: 7 additions & 14 deletions libsolidity/experimental/analysis/TypeInference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,7 @@ bool TypeInference::visit(TypeClassDefinition const& _typeClassDefinition)
subNode->accept(*this);
auto const* functionDefinition = dynamic_cast<FunctionDefinition const*>(subNode.get());
solAssert(functionDefinition);
// TODO: need polymorphicInstance?
auto functionType = polymorphicInstance(typeAnnotation(*functionDefinition));
auto functionType = typeAnnotation(*functionDefinition);
if (!functionTypes.emplace(functionDefinition->name(), functionType).second)
m_errorReporter.fatalTypeError(3195_error, functionDefinition->location(), "Function in type class declared multiple times.");
auto typeVars = TypeEnvironmentHelpers{*m_env}.typeVars(functionType);
Expand Down Expand Up @@ -481,7 +480,10 @@ experimental::Type TypeInference::handleIdentifierByReferencedDeclaration(langut
else if (dynamic_cast<FunctionDefinition const*>(&_declaration))
return polymorphicInstance(*declarationAnnotation.type);
else if (dynamic_cast<TypeClassDefinition const*>(&_declaration))
return polymorphicInstance(*declarationAnnotation.type);
{
solAssert(TypeEnvironmentHelpers{*m_env}.typeVars(*declarationAnnotation.type).empty());
return *declarationAnnotation.type;
}
else if (dynamic_cast<TypeDefinition const*>(&_declaration))
{
// TODO: can we avoid this?
Expand Down Expand Up @@ -1069,18 +1071,9 @@ TypeRegistration::TypeClassInstantiations const& typeClassInstantiations(Analysi
}
}

void TypeInference::unifyGeneralized(Type _type, Type _scheme, std::vector<Type> _monomorphicTypes, langutil::SourceLocation _location)
{
solUnimplementedAssert(_monomorphicTypes.empty(), "unsupported");
Type fresh = m_env->fresh(_scheme);
unify(_type, fresh, _location);
}

experimental::Type TypeInference::polymorphicInstance(Type _scheme, langutil::SourceLocation _location)
experimental::Type TypeInference::polymorphicInstance(Type const& _scheme)
{
Type result = m_typeSystem.freshTypeVariable({});
unifyGeneralized(result, _scheme, {}, _location);
return result;
return m_env->fresh(_scheme);
}

void TypeInference::unify(Type _a, Type _b, langutil::SourceLocation _location)
Expand Down
4 changes: 2 additions & 2 deletions libsolidity/experimental/analysis/TypeInference.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,8 @@ class TypeInference: public ASTConstVisitor
GlobalAnnotation& annotation();

void unify(Type _a, Type _b, langutil::SourceLocation _location = {});
void unifyGeneralized(Type _type, Type _scheme, std::vector<Type> _monomorphicTypes, langutil::SourceLocation _location = {});
Type polymorphicInstance(Type _scheme, langutil::SourceLocation _location = {});
/// Creates a polymorphic instance of a global type scheme
Type polymorphicInstance(Type const& _scheme);
Type memberType(Type _type, std::string _memberName, langutil::SourceLocation _location = {});
enum class ExpressionContext { Term, Type, Sort };
Type handleIdentifierByReferencedDeclaration(langutil::SourceLocation _location, Declaration const& _declaration);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,9 @@ contract C {
// Info 4164: (525-529): Inferred type: word
// Info 4164: (540-553): Inferred type: bool
// Info 4164: (540-550): Inferred type: (bool, word) -> bool
// Info 4164: (540-544): Inferred type: ('cb:type, 'cc:type)
// Info 4164: (540-544): Inferred type: ('bl:type, 'bm:type)
// Info 4164: (551-552): Inferred type: (bool, word)
// Info 4164: (563-577): Inferred type: word
// Info 4164: (563-574): Inferred type: (bool, word) -> word
// Info 4164: (563-567): Inferred type: ('ci:type, 'cj:type)
// Info 4164: (563-567): Inferred type: ('bq:type, 'br:type)
// Info 4164: (575-576): Inferred type: (bool, word)
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pragma experimental solidity;

type T;
type U;

function f(x: T, y: U) {}

function run(a: U, b: T) {
f(a, b);
}
// ====
// EVMVersion: >=constantinople
// ----
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
// TypeError 8456: (106-113): Cannot unify T and U.
// TypeError 8456: (106-113): Cannot unify U and T.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
pragma experimental solidity;

type T;
type U(A);

function f(x, y: X, z: U(Y)) {}

function run(a: T, b: U(T), c: U(U(T))) {
f(a, a, b);
f(b, b, c);
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: true
// ----
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
// Info 4164: (31-38): Inferred type: T
// Info 4164: (39-49): Inferred type: tfun('u:type, U('u:type))
// Info 4164: (45-48): Inferred type: 't:type
// Info 4164: (46-47): Inferred type: 't:type
// Info 4164: (51-82): Inferred type: ('x:type, 'y:type, U('ba:type)) -> ()
// Info 4164: (61-79): Inferred type: ('x:type, 'y:type, U('ba:type))
// Info 4164: (62-63): Inferred type: 'x:type
// Info 4164: (65-69): Inferred type: 'y:type
// Info 4164: (68-69): Inferred type: 'y:type
// Info 4164: (71-78): Inferred type: U('ba:type)
// Info 4164: (74-78): Inferred type: U('ba:type)
// Info 4164: (74-75): Inferred type: tfun('ba:type, U('ba:type))
// Info 4164: (76-77): Inferred type: 'ba:type
// Info 4164: (84-159): Inferred type: (T, U(T), U(U(T))) -> ()
// Info 4164: (96-123): Inferred type: (T, U(T), U(U(T)))
// Info 4164: (97-101): Inferred type: T
// Info 4164: (100-101): Inferred type: T
// Info 4164: (103-110): Inferred type: U(T)
// Info 4164: (106-110): Inferred type: U(T)
// Info 4164: (106-107): Inferred type: tfun(T, U(T))
// Info 4164: (108-109): Inferred type: T
// Info 4164: (112-122): Inferred type: U(U(T))
// Info 4164: (115-122): Inferred type: U(U(T))
// Info 4164: (115-116): Inferred type: tfun(U(T), U(U(T)))
// Info 4164: (117-121): Inferred type: U(T)
// Info 4164: (117-118): Inferred type: tfun(T, U(T))
// Info 4164: (119-120): Inferred type: T
// Info 4164: (130-140): Inferred type: ()
// Info 4164: (130-131): Inferred type: (T, T, U(T)) -> ()
// Info 4164: (132-133): Inferred type: T
// Info 4164: (135-136): Inferred type: T
// Info 4164: (138-139): Inferred type: U(T)
// Info 4164: (146-156): Inferred type: ()
// Info 4164: (146-147): Inferred type: (U(T), U(T), U(U(T))) -> ()
// Info 4164: (148-149): Inferred type: U(T)
// Info 4164: (151-152): Inferred type: U(T)
// Info 4164: (154-155): Inferred type: U(U(T))
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
pragma experimental solidity;

type T;
type U;

function f(x) {}

function run(a: T, b: U) {
// NOTE: The type of f is polymorphic but the inferred type of g is not - this would be
// let-polymorphism, which we decided not to support.
let g = f;
g(a);
g(b);
}
// ====
// EVMVersion: >=constantinople
// ----
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
// TypeError 8456: (272-276): Cannot unify T and U.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
pragma experimental solidity;

type T(A);
type U;
type V;

function f(x: T(U)) {}

function run(a: T(V)) {
f(a);
}
// ====
// EVMVersion: >=constantinople
// ----
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
// TypeError 8456: (111-115): Cannot unify U and V.
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
pragma experimental solidity;

type T(P, Q, R);
type U;
type V;

class Self: C {}
class Self: D {}

function run() {
let x: T(U, X, Z: C);
let y: T(V, Y, Z: D);
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: true
// ----
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
// Info 4164: (31-47): Inferred type: tfun(('ba:type, 'bb:type, 'bc:type), T('ba:type, 'bb:type, 'bc:type))
// Info 4164: (37-46): Inferred type: ('x:type, 'y:type, 'z:type)
// Info 4164: (38-39): Inferred type: 'x:type
// Info 4164: (41-42): Inferred type: 'y:type
// Info 4164: (44-45): Inferred type: 'z:type
// Info 4164: (48-55): Inferred type: U
// Info 4164: (56-63): Inferred type: V
// Info 4164: (65-81): Inferred type: C
// Info 4164: (71-75): Inferred type: 'be:(type, C)
// Info 4164: (82-98): Inferred type: D
// Info 4164: (88-92): Inferred type: 'bg:(type, D)
// Info 4164: (100-170): Inferred type: () -> ()
// Info 4164: (112-114): Inferred type: ()
// Info 4164: (125-141): Inferred type: T(U, 'bm:type, 'bo:(type, C))
// Info 4164: (128-141): Inferred type: T(U, 'bm:type, 'bo:(type, C))
// Info 4164: (128-129): Inferred type: tfun((U, 'bm:type, 'bo:(type, C)), T(U, 'bm:type, 'bo:(type, C)))
// Info 4164: (130-131): Inferred type: U
// Info 4164: (133-134): Inferred type: 'bm:type
// Info 4164: (136-140): Inferred type: 'bo:(type, C)
// Info 4164: (136-137): Inferred type: 'bo:(type, C)
// Info 4164: (139-140): Inferred type: 'bo:(type, C)
// Info 4164: (151-167): Inferred type: T(V, 'bt:type, 'bv:(type, D))
// Info 4164: (154-167): Inferred type: T(V, 'bt:type, 'bv:(type, D))
// Info 4164: (154-155): Inferred type: tfun((V, 'bt:type, 'bv:(type, D)), T(V, 'bt:type, 'bv:(type, D)))
// Info 4164: (156-157): Inferred type: V
// Info 4164: (159-160): Inferred type: 'bt:type
// Info 4164: (162-166): Inferred type: 'bv:(type, D)
// Info 4164: (162-163): Inferred type: 'bv:(type, D)
// Info 4164: (165-166): Inferred type: 'bv:(type, D)
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
pragma experimental solidity;

type uint;
type string;

type T(A);
type U(B) = T(B);

function fun() {
let w: U(uint);
let v: T(uint);
U.rep(w);
U.abs(v);

let s: U(string);
let t: T(string);
U.rep(s);
U.abs(t);
}
// ====
// EVMVersion: >=constantinople
// compileViaYul: true
// ----
// Warning 2264: (0-29): Experimental features are turned on. Do not use experimental features on live deployments.
// Info 4164: (31-41): Inferred type: uint
// Info 4164: (42-54): Inferred type: string
// Info 4164: (56-66): Inferred type: tfun('v:type, T('v:type))
// Info 4164: (62-65): Inferred type: 'u:type
// Info 4164: (63-64): Inferred type: 'u:type
// Info 4164: (67-84): Inferred type: tfun('x:type, U('x:type))
// Info 4164: (73-76): Inferred type: 'w:type
// Info 4164: (74-75): Inferred type: 'w:type
// Info 4164: (79-83): Inferred type: T('w:type)
// Info 4164: (79-80): Inferred type: tfun('w:type, T('w:type))
// Info 4164: (81-82): Inferred type: 'w:type
// Info 4164: (86-245): Inferred type: () -> ()
// Info 4164: (98-100): Inferred type: ()
// Info 4164: (111-121): Inferred type: U(uint)
// Info 4164: (114-121): Inferred type: U(uint)
// Info 4164: (114-115): Inferred type: tfun(uint, U(uint))
// Info 4164: (116-120): Inferred type: uint
// Info 4164: (131-141): Inferred type: T(uint)
// Info 4164: (134-141): Inferred type: T(uint)
// Info 4164: (134-135): Inferred type: tfun(uint, T(uint))
// Info 4164: (136-140): Inferred type: uint
// Info 4164: (147-155): Inferred type: T('bi:type)
// Info 4164: (147-152): Inferred type: U(uint) -> T('bi:type)
// Info 4164: (147-148): Inferred type: U('bg:type)
// Info 4164: (153-154): Inferred type: U(uint)
// Info 4164: (161-169): Inferred type: U('bm:type)
// Info 4164: (161-166): Inferred type: T(uint) -> U('bm:type)
// Info 4164: (161-162): Inferred type: U('bk:type)
// Info 4164: (167-168): Inferred type: T(uint)
// Info 4164: (180-192): Inferred type: U(string)
// Info 4164: (183-192): Inferred type: U(string)
// Info 4164: (183-184): Inferred type: tfun(string, U(string))
// Info 4164: (185-191): Inferred type: string
// Info 4164: (202-214): Inferred type: T(string)
// Info 4164: (205-214): Inferred type: T(string)
// Info 4164: (205-206): Inferred type: tfun(string, T(string))
// Info 4164: (207-213): Inferred type: string
// Info 4164: (220-228): Inferred type: T('bu:type)
// Info 4164: (220-225): Inferred type: U(string) -> T('bu:type)
// Info 4164: (220-221): Inferred type: U('bs:type)
// Info 4164: (226-227): Inferred type: U(string)
// Info 4164: (234-242): Inferred type: U('by:type)
// Info 4164: (234-239): Inferred type: T(string) -> U('by:type)
// Info 4164: (234-235): Inferred type: U('bw:type)
// Info 4164: (240-241): Inferred type: T(string)
Loading

0 comments on commit 826c168

Please sign in to comment.