-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[CSBindings] Avoid binding type variables to collection types directly #13109
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 This is the idea I had for fixing array subtyping problem when passed as an argument. WDYT? |
@xedin It seems that either the fix should be more fundamental, or any explicit enumeration of these cases should also include optionals and any other covariant type constructor (functions? tuples?). What's the actual underlying problem here? |
@slavapestov Here is the problem this is trying to solve:
Currently this is not going to compile because
is what is going to be generated when solver matches I think better solution would be to move this logic into |
lib/Sema/CSSolver.cpp
Outdated
auto UGT = UnboundGenericType::get(BGT->getDecl(), BGT->getParent(), | ||
BGT->getASTContext()); | ||
|
||
type = openUnboundGenericType(UGT, typeVar->getImpl().getLocator()); |
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.
It's probably worth calling reconstituteSugar
, as in the previous code, so we get prettier types.
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.
This is effectively dropping all information about the type arguments to Array
/ Set
/ Dictionary
. I guess that's okay because whatever constraint we inferred this type binding from will still be there to help bind these type variables.
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.
Will do re: reconstituteSugar
, was wondering if we really need it there... Regarding information - yes, that's the intent, to use fresh type variables here so conversion could be done properly.
lib/Sema/CSSolver.cpp
Outdated
// types, that's going to ensure that subtype relationship is | ||
// always preserved. | ||
if (isConcreteCollectionType(type)) { | ||
auto *BGT = type->getAs<BoundGenericType>(); |
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.
FWIW, in cases where getAs
should never fail, you should use castTo
to always get a non-null pointer (or assert if it's not of the right type).
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, I didn't know that!
lib/Sema/CSSolver.cpp
Outdated
// bind using temporary type variables substituted for element | ||
// types, that's going to ensure that subtype relationship is | ||
// always preserved. | ||
if (isConcreteCollectionType(type)) { |
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.
This should probably be an else if
clause of the if
above, since we don't want to look back at a type that we just opened to type variables.
@DougGregor I've made it so potential bindings now track their source kind and when we attempt the bindings we only do open again for collections if they type comes from argument conversion. WDYT? |
@swift-ci please test |
@swift-ci please test source compatibility |
lib/Sema/CSSolver.cpp
Outdated
// bind using temporary type variables substituted for element | ||
// types, that's going to ensure that subtype relationship is | ||
// always preserved. | ||
if ((binding.BindingSource == ConstraintKind::ArgumentConversion || |
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.
"else if"?
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.
Yes, I forgot to change that from previous version, will do!
// rdar://problem/35541153 - Generic parameter inference bug | ||
|
||
func rdar35541153() { | ||
func foo<U: Equatable, V: Equatable, C: Collection>(_ c: C) where C.Element == (U, V) {} |
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.
Could you add a second example here where the the function in question takes two parameters? I want to be sure that ParenType
and TupleType
function inputs don't end up getting different behavior.
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.
Sure!
Instead of binding collection types directly let's try to bind using temporary type variables substituted for element types, that's going to ensure that subtype relationship is always preserved. Resolves: rdar://problem/35541153
@DougGregor All done! |
@swift-ci please test |
@swift-ci please test source compatibility |
Instead of binding collection types directly let's try to
bind using temporary type variables substituted for element
types, that's going to ensure that subtype relationship is
always preserved.
Resolves: rdar://problem/35541153