Implement SE-0195, which introduces "Dynamic Member Lookup" Types (#14546)

* Implement the recently accepted SE-0195 proposal, which introduces "Dynamic
Member Lookup" Types.  This is a dusted off and updated version of PR13361,
which switches from DynamicMemberLookupProtocol to @dynamicMemberLookup as
was requested by the final review decision.  This also rebases it,
updates it for other changes in the compiler, fixes a bunch of bugs, and adds support for keypaths.  

Thank you to @rudx and @DougGregor in particular for the helpful review comments and test cases!
This commit is contained in:
Chris Lattner
2018-02-16 16:19:50 -08:00
committed by GitHub
parent 3184dd8ad4
commit a0fa5d11b4
17 changed files with 845 additions and 71 deletions

View File

@@ -528,8 +528,9 @@ static bool diagnoseAmbiguity(ConstraintSystem &cs,
break;
case OverloadChoiceKind::KeyPathApplication:
// Skip key path applications, since we don't want them to noise up
// unrelated subscript diagnostics.
case OverloadChoiceKind::DynamicMemberLookup:
// Skip key path applications and dynamic member lookups, since we don't
// want them to noise up unrelated subscript diagnostics.
break;
case OverloadChoiceKind::BaseType:
@@ -3151,9 +3152,17 @@ void ConstraintSystem::diagnoseAssignmentFailure(Expr *dest, Type destTy,
diagID = diag::assignment_bang_has_immutable_subcomponent;
else if (isa<UnresolvedDotExpr>(dest) || isa<MemberRefExpr>(dest))
diagID = diag::assignment_lhs_is_immutable_property;
else if (isa<SubscriptExpr>(dest))
else if (auto sub = dyn_cast<SubscriptExpr>(dest)) {
diagID = diag::assignment_subscript_has_immutable_base;
else {
// If the destination is a subscript with a 'dynamicLookup:' label and if
// the tuple is implicit, then this was actually a @dynamicMemberLookup
// access. Emit a more specific diagnostic.
if (sub->getIndex()->isImplicit() &&
sub->getArgumentLabels().size() == 1 &&
sub->getArgumentLabels().front() == TC.Context.Id_dynamicMember)
diagID = diag::assignment_dynamic_property_has_immutable_base;
} else {
diagID = diag::assignment_lhs_is_immutable_variable;
}
@@ -4526,7 +4535,8 @@ bool FailureDiagnosis::diagnoseParameterErrors(CalleeCandidateInfo &CCI,
return false;
}
bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE, bool inAssignmentDestination) {
bool FailureDiagnosis::diagnoseSubscriptErrors(SubscriptExpr *SE,
bool inAssignmentDestination) {
auto baseExpr = typeCheckChildIndependently(SE->getBase());
if (!baseExpr) return true;
auto baseType = CS.getType(baseExpr);