Skip to content

Commit a7bc52f

Browse files
authored
Merge pull request swiftlang#28197 from xedin/handle-single-pd-arg-mismatch
[Diagnostics] Produce a tailored diagnostic for property wrapper argu…
2 parents 7004322 + 08f8f41 commit a7bc52f

File tree

4 files changed

+35
-11
lines changed

4 files changed

+35
-11
lines changed

lib/Sema/CSDiagnostics.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5293,6 +5293,9 @@ bool ArgumentMismatchFailure::diagnoseAsError() {
52935293
if (diagnoseUseOfReferenceEqualityOperator())
52945294
return true;
52955295

5296+
if (diagnosePropertyWrapperMismatch())
5297+
return true;
5298+
52965299
auto argType = getFromType();
52975300
auto paramType = getToType();
52985301

@@ -5532,6 +5535,32 @@ bool ArgumentMismatchFailure::diagnoseMisplacedMissingArgument() const {
55325535
return failure.diagnoseSingleMissingArgument();
55335536
}
55345537

5538+
bool ArgumentMismatchFailure::diagnosePropertyWrapperMismatch() const {
5539+
auto argType = getFromType();
5540+
auto paramType = getToType();
5541+
5542+
// Verify that this is an implicit call to a property wrapper initializer
5543+
// in a form of `init(wrappedValue:)` or deprecated `init(initialValue:)`.
5544+
auto *call = dyn_cast<CallExpr>(getRawAnchor());
5545+
if (!(call && call->isImplicit() && isa<TypeExpr>(call->getFn()) &&
5546+
call->getNumArguments() == 1 &&
5547+
(call->getArgumentLabels().front() == getASTContext().Id_wrappedValue ||
5548+
call->getArgumentLabels().front() == getASTContext().Id_initialValue)))
5549+
return false;
5550+
5551+
auto argExpr = cast<TupleExpr>(call->getArg())->getElement(0);
5552+
// If this is an attempt to initialize property wrapper with opaque value
5553+
// of error type, let's just ignore that problem since original mismatch
5554+
// has been diagnosed already.
5555+
if (argExpr->isImplicit() && isa<OpaqueValueExpr>(argExpr) &&
5556+
argType->is<ErrorType>())
5557+
return true;
5558+
5559+
emitDiagnostic(getLoc(), diag::cannot_convert_initializer_value, argType,
5560+
paramType);
5561+
return true;
5562+
}
5563+
55355564
void ExpandArrayIntoVarargsFailure::tryDropArrayBracketsFixIt(
55365565
Expr *anchor) const {
55375566
// If this is an array literal, offer to remove the brackets and pass the

lib/Sema/CSDiagnostics.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1845,6 +1845,11 @@ class ArgumentMismatchFailure : public ContextualFailure {
18451845
/// reference equality operators `===` and `!==`.
18461846
bool diagnoseUseOfReferenceEqualityOperator() const;
18471847

1848+
/// Tailored diagnostics for type mismatches associated with
1849+
/// property wrapper initialization via implicit `init(wrappedValue:)`
1850+
/// or now deprecated `init(initialValue:)`.
1851+
bool diagnosePropertyWrapperMismatch() const;
1852+
18481853
protected:
18491854
/// \returns The position of the argument being diagnosed, starting at 1.
18501855
unsigned getArgPosition() const { return Info->getArgPosition(); }

lib/Sema/CSSimplify.cpp

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3078,16 +3078,6 @@ bool ConstraintSystem::repairFailures(
30783078
locator);
30793079
}
30803080

3081-
// Let's not complain about argument type mismatch if we have a synthesized
3082-
// wrappedValue initializer, because we already emit a diagnostic for a
3083-
// type mismatch between the property's type and the wrappedValue type.
3084-
if (auto CE = dyn_cast<CallExpr>(loc->getAnchor())) {
3085-
if (CE->isImplicit() && !CE->getArgumentLabels().empty() &&
3086-
CE->getArgumentLabels().front() == getASTContext().Id_wrappedValue) {
3087-
break;
3088-
}
3089-
}
3090-
30913081
// If either type has a hole, consider this fixed.
30923082
if (lhs->hasUnresolvedType() || rhs->hasUnresolvedType())
30933083
return true;

test/decl/var/property_wrappers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ struct Initialization {
245245
var y = true
246246

247247
@WrapperWithInitialValue<Int>
248-
var y2 = true // expected-error{{Bool' is not convertible to 'Int}}
248+
var y2 = true // expected-error{{cannot convert value of type 'Bool' to specified type 'Int'}}
249249

250250
mutating func checkTypes(s: String) {
251251
x2 = s // expected-error{{cannot assign value of type 'String' to type 'Double'}}

0 commit comments

Comments
 (0)