-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[AST] Fix canonicalization of the function input types #12304
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@DougGregor I'm not sure about one thing - do we need a flag for |
@xedin I think it would be better to represent all types in the correct way for Swift 4, and have Swift 3 mode simulated with various implicit coercions. |
lib/AST/Type.cpp
Outdated
@@ -1022,6 +1022,31 @@ void ProtocolType::canonicalizeProtocols( | |||
llvm::array_pod_sort(protocols.begin(), protocols.end(), compareProtocols); | |||
} | |||
|
|||
static Type | |||
getCanonicalInputType(AnyFunctionType *funcType, | |||
std::function<CanType(Type)> getCanonicalType) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use llvm::function_ref
instead of std::function
here, because we're not going to save the function anywhere.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
lib/AST/Type.cpp
Outdated
getCanonicalInputType(AnyFunctionType *funcType, | ||
std::function<CanType(Type)> getCanonicalType) { | ||
auto inputType = funcType->getInput(); | ||
if (auto *TT = dyn_cast<TupleType>(inputType.getPointer())) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need this if
here; the fall through will work fine.
lib/AST/Type.cpp
Outdated
if (auto *TT = dyn_cast<TupleType>(inputType.getPointer())) | ||
return getCanonicalType(TT); | ||
|
||
if (auto *PT = dyn_cast<ParenType>(inputType.getPointer())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this logic be simpler? It seems like we could do something like:
bool isParen = isa<ParenType>(inputType.getPointer());
inputType = inputType->getCanonicalType();
if (isParen) inputType = ParenType::get(inputType);
assert(AnyFunctionType::isCanonicalFunctionInputType(inputType));
Canonicalization should always do the right thing (regardless of language dialect), and we can teach the type checker about extra implicit conversions if needed. |
87fea3f
to
703080f
Compare
Currently canonicalization of the input type was happening standalone which means that outer parens are regarded as suger and removed, this is incorrect after SE-0110 and such parens can't be stripped.
703080f
to
7d2e29a
Compare
@DougGregor How does it look now? |
@swift-ci please smoke test |
@swift-ci please test source compatibility |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Beautiful, thank you!
Currently canonicalization of the input type was happening standalone
which means that outer parens are regarded as suger and removed,
this is incorrect after SE-0110 and such parens can't be stripped.