@@ -3099,10 +3099,8 @@ static bool isIntegerType(Type fromType, ConstraintSystem *CS) {
3099
3099
CS);
3100
3100
}
3101
3101
3102
- // / Return true if the given type conforms to RawRepresentable, with an
3103
- // / underlying type conforming to the given known protocol.
3102
+ // / Return true if the given type conforms to RawRepresentable.
3104
3103
static Type isRawRepresentable (Type fromType,
3105
- KnownProtocolKind kind,
3106
3104
ConstraintSystem *CS) {
3107
3105
auto rawReprType =
3108
3106
CS->TC .getProtocol (SourceLoc (), KnownProtocolKind::RawRepresentable);
@@ -3119,6 +3117,15 @@ static Type isRawRepresentable(Type fromType,
3119
3117
conformance,
3120
3118
CS->getASTContext ().getIdentifier (" RawValue" ),
3121
3119
&CS->TC );
3120
+ return rawTy;
3121
+ }
3122
+
3123
+ // / Return true if the given type conforms to RawRepresentable, with an
3124
+ // / underlying type conforming to the given known protocol.
3125
+ static Type isRawRepresentable (Type fromType,
3126
+ KnownProtocolKind kind,
3127
+ ConstraintSystem *CS) {
3128
+ Type rawTy = isRawRepresentable (fromType, CS);
3122
3129
if (!rawTy || !isLiteralConvertibleType (rawTy, kind, CS))
3123
3130
return Type ();
3124
3131
@@ -3800,6 +3807,45 @@ static bool diagnoseSingleCandidateFailures(CalleeCandidateInfo &CCI,
3800
3807
}
3801
3808
}
3802
3809
3810
+ // Check the case where a raw-representable type is constructed from an
3811
+ // argument with the same type:
3812
+ //
3813
+ // MyEnumType(MyEnumType.foo)
3814
+ //
3815
+ // This is missing 'rawValue:' label, but a better fix is to just remove the
3816
+ // unnecessary constructor call:
3817
+ //
3818
+ // MyEnumType.foo
3819
+ //
3820
+ if (params.size () == 1 && args.size () == 1 &&
3821
+ candidate.getDecl () && isa<ConstructorDecl>(candidate.getDecl ()) &&
3822
+ candidate.level == 1 ) {
3823
+ CallArgParam &arg = args[0 ];
3824
+ auto resTy = candidate.getResultType ();
3825
+ if (auto unwrappedOpt = resTy->getOptionalObjectType ())
3826
+ resTy = unwrappedOpt;
3827
+ auto rawTy = isRawRepresentable (resTy, CCI.CS );
3828
+ if (rawTy && resTy->getCanonicalType () == arg.Ty .getCanonicalTypeOrNull ()) {
3829
+ auto getInnerExpr = [](Expr *E) -> Expr* {
3830
+ ParenExpr *parenE = dyn_cast<ParenExpr>(E);
3831
+ if (!parenE)
3832
+ return nullptr ;
3833
+ return parenE->getSubExpr ();
3834
+ };
3835
+ Expr *innerE = getInnerExpr (argExpr);
3836
+
3837
+ InFlightDiagnostic diag = TC.diagnose (fnExpr->getLoc (),
3838
+ diag::invalid_initialization_parameter_same_type, resTy);
3839
+ diag.highlight ((innerE ? innerE : argExpr)->getSourceRange ());
3840
+ if (innerE) {
3841
+ // Remove the unnecessary constructor call.
3842
+ diag.fixItRemoveChars (fnExpr->getLoc (), innerE->getStartLoc ())
3843
+ .fixItRemove (argExpr->getEndLoc ());
3844
+ }
3845
+ return true ;
3846
+ }
3847
+ }
3848
+
3803
3849
// We only handle structural errors here.
3804
3850
if (CCI.closeness != CC_ArgumentLabelMismatch &&
3805
3851
CCI.closeness != CC_ArgumentCountMismatch)
0 commit comments