Skip to content

[ConstraintSystem] Use lightweight conformance check in determining w… #25348

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

Merged
merged 1 commit into from
Jun 12, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 18 additions & 15 deletions lib/Sema/TypeCheckConstraints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1972,15 +1972,21 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
Type type;
if (typeExpr->getTypeLoc().wasValidated()) {
type = typeExpr->getTypeLoc().getType();
} else if (auto *rep = typeExpr->getTypeRepr()) {
} else {
TypeResolutionOptions options(TypeResolverContext::InExpression);
options |= TypeResolutionFlags::AllowUnboundGenerics;
auto resolution = TypeResolution::forContextual(DC);
type = resolution.resolveType(rep, options);
typeExpr->getTypeLoc().setType(type);

auto &typeLoc = typeExpr->getTypeLoc();
bool hadError =
TC.validateType(typeLoc, TypeResolution::forContextual(DC), options);

if (hadError)
return nullptr;

type = typeLoc.getType();
}

if (!type)
if (!type || !type->getAnyNominal())
return nullptr;

// Don't bother to convert deprecated selector syntax.
Expand All @@ -1989,16 +1995,13 @@ Expr *PreCheckExpression::simplifyTypeConstructionWithLiteralArg(Expr *E) {
return nullptr;
}

ConformanceCheckOptions options;
options |= ConformanceCheckFlags::InExpression;
options |= ConformanceCheckFlags::SkipConditionalRequirements;

auto result = TypeChecker::conformsToProtocol(type, protocol, DC, options);
if (!result || !result->isConcrete())
return nullptr;

return CoerceExpr::forLiteralInit(TC.Context, argExpr, call->getSourceRange(),
typeExpr->getTypeLoc());
auto *NTD = type->getAnyNominal();
SmallVector<ProtocolConformance *, 2> conformances;
return NTD->lookupConformance(DC->getParentModule(), protocol, conformances)
? CoerceExpr::forLiteralInit(TC.Context, argExpr,
call->getSourceRange(),
typeExpr->getTypeLoc())
: nullptr;
}

/// Pre-check the expression, validating any types that occur in the
Expand Down
13 changes: 13 additions & 0 deletions test/Constraints/generics.swift
Original file line number Diff line number Diff line change
Expand Up @@ -757,3 +757,16 @@ func test_generic_subscript_with_missing_arg() {
_ = s[0] // expected-error {{generic parameter 'U' could not be inferred}}
}
}

func rdar_50007727() {
struct A<T> { // expected-note {{'T' declared as parameter to type 'A'}}
struct B<U> : ExpressibleByStringLiteral {
init(stringLiteral value: String) {}
}
}

struct S {}
let _ = A.B<S>("hello")
// expected-error@-1 {{generic parameter 'T' could not be inferred in cast to 'A.B'}}
// expected-note@-2 {{explicitly specify the generic arguments to fix this issue}} {{12-12=<Any>}}
}