diff --git a/include/swift/AST/DiagnosticsSema.def b/include/swift/AST/DiagnosticsSema.def index f8c89e56b84f2..772a3ad7b8af3 100644 --- a/include/swift/AST/DiagnosticsSema.def +++ b/include/swift/AST/DiagnosticsSema.def @@ -4605,10 +4605,10 @@ NOTE(duplicated_key_declared_here, none, // Generic specializations ERROR(cannot_explicitly_specialize_generic_function,none, "cannot explicitly specialize a generic function", ()) -ERROR(not_a_generic_definition,none, - "cannot specialize a non-generic definition", ()) ERROR(not_a_generic_type,none, "cannot specialize non-generic type %0", (Type)) +ERROR(not_a_generic_macro,none, + "cannot specialize a non-generic external macro %0", (const ValueDecl *)) ERROR(protocol_declares_unknown_primary_assoc_type,none, "an associated type named %0 must be declared in the protocol %1 or a protocol it inherits", (Identifier, Type)) diff --git a/include/swift/AST/Types.h b/include/swift/AST/Types.h index d5fcf0a4154d7..4677bdf6f239f 100644 --- a/include/swift/AST/Types.h +++ b/include/swift/AST/Types.h @@ -7327,7 +7327,7 @@ class PlaceholderType : public TypeBase { // recursive property logic in PlaceholderType::get. using Originator = llvm::PointerUnion; + ErrorExpr *, TypeRepr *>; Originator O; diff --git a/include/swift/Sema/CSFix.h b/include/swift/Sema/CSFix.h index 61f050bb8b82b..8a113aeddba08 100644 --- a/include/swift/Sema/CSFix.h +++ b/include/swift/Sema/CSFix.h @@ -462,9 +462,12 @@ enum class FixKind : uint8_t { /// because its name doesn't appear in 'initializes' or 'accesses' attributes. AllowInvalidMemberReferenceInInitAccessor, - /// Ignore an attempt to specialize non-generic type. + /// Ignore an attempt to specialize a non-generic type. AllowConcreteTypeSpecialization, + /// Ignore an attempt to specialize a generic function. + AllowGenericFunctionSpecialization, + /// Ignore an out-of-place \c then statement. IgnoreOutOfPlaceThenStmt, @@ -3718,11 +3721,14 @@ class AllowInvalidMemberReferenceInInitAccessor final : public ConstraintFix { class AllowConcreteTypeSpecialization final : public ConstraintFix { Type ConcreteType; + ValueDecl *Decl; AllowConcreteTypeSpecialization(ConstraintSystem &cs, Type concreteTy, - ConstraintLocator *locator) - : ConstraintFix(cs, FixKind::AllowConcreteTypeSpecialization, locator), - ConcreteType(concreteTy) {} + ValueDecl *decl, ConstraintLocator *locator, + FixBehavior fixBehavior) + : ConstraintFix(cs, FixKind::AllowConcreteTypeSpecialization, locator, + fixBehavior), + ConcreteType(concreteTy), Decl(decl) {} public: std::string getName() const override { @@ -3736,13 +3742,41 @@ class AllowConcreteTypeSpecialization final : public ConstraintFix { } static AllowConcreteTypeSpecialization * - create(ConstraintSystem &cs, Type concreteTy, ConstraintLocator *locator); + create(ConstraintSystem &cs, Type concreteTy, ValueDecl *decl, + ConstraintLocator *locator, FixBehavior fixBehavior); static bool classof(const ConstraintFix *fix) { return fix->getKind() == FixKind::AllowConcreteTypeSpecialization; } }; +class AllowGenericFunctionSpecialization final : public ConstraintFix { + ValueDecl *Decl; + + AllowGenericFunctionSpecialization(ConstraintSystem &cs, ValueDecl *decl, + ConstraintLocator *locator) + : ConstraintFix(cs, FixKind::AllowGenericFunctionSpecialization, locator), + Decl(decl) {} + +public: + std::string getName() const override { + return "allow generic function specialization"; + } + + bool diagnose(const Solution &solution, bool asNote = false) const override; + + bool diagnoseForAmbiguity(CommonFixesArray commonFixes) const override { + return diagnose(*commonFixes.front().first); + } + + static AllowGenericFunctionSpecialization * + create(ConstraintSystem &cs, ValueDecl *decl, ConstraintLocator *locator); + + static bool classof(const ConstraintFix *fix) { + return fix->getKind() == FixKind::AllowGenericFunctionSpecialization; + } +}; + class IgnoreOutOfPlaceThenStmt final : public ConstraintFix { IgnoreOutOfPlaceThenStmt(ConstraintSystem &cs, ConstraintLocator *locator) : ConstraintFix(cs, FixKind::IgnoreOutOfPlaceThenStmt, locator) {} diff --git a/include/swift/Sema/ConstraintLocator.h b/include/swift/Sema/ConstraintLocator.h index 198a87887947a..631e84cdcc24d 100644 --- a/include/swift/Sema/ConstraintLocator.h +++ b/include/swift/Sema/ConstraintLocator.h @@ -985,13 +985,13 @@ class LocatorPathElt::ConformanceRequirement final }; class LocatorPathElt::PlaceholderType final - : public StoredPointerElement { + : public StoredPointerElement { public: - PlaceholderType(PlaceholderTypeRepr *placeholderRepr) + PlaceholderType(TypeRepr *placeholderRepr) : StoredPointerElement(PathElementKind::PlaceholderType, placeholderRepr) {} - PlaceholderTypeRepr *getPlaceholderRepr() const { return getStoredPointer(); } + TypeRepr *getPlaceholderRepr() const { return getStoredPointer(); } static bool classof(const LocatorPathElt *elt) { return elt->getKind() == ConstraintLocator::PlaceholderType; diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 4dde6b4631e4a..b473100c39d7d 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -3987,8 +3987,8 @@ namespace { printFlag("error_expr"); } else if (auto *DMT = originator.dyn_cast()) { printRec(DMT, "dependent_member_type"); - } else if (originator.is()) { - printFlag("placeholder_type_repr"); + } else if (originator.is()) { + printFlag("type_repr"); } else { assert(false && "unknown originator"); } diff --git a/lib/AST/ASTPrinter.cpp b/lib/AST/ASTPrinter.cpp index 133c15b2bf7ff..c60663619e18f 100644 --- a/lib/AST/ASTPrinter.cpp +++ b/lib/AST/ASTPrinter.cpp @@ -5870,8 +5870,8 @@ class TypePrinter : public TypeVisitor { Printer << "error_expr"; } else if (auto *DMT = originator.dyn_cast()) { visit(DMT); - } else if (originator.is()) { - Printer << "placeholder_type_repr"; + } else if (originator.is()) { + Printer << "type_repr"; } else { assert(false && "unknown originator"); } diff --git a/lib/Parse/ParseType.cpp b/lib/Parse/ParseType.cpp index 632e3e3e27420..038170d0ae459 100644 --- a/lib/Parse/ParseType.cpp +++ b/lib/Parse/ParseType.cpp @@ -1476,7 +1476,9 @@ static bool isGenericTypeDisambiguatingToken(Parser &P) { auto &tok = P.Tok; switch (tok.getKind()) { default: - return false; + // If this is the end of the expr (wouldn't match parseExprSequenceElement), + // prefer generic type list over an illegal unary postfix '>' operator. + return P.isStartOfSwiftDecl() || P.isStartOfStmt(/*prefer expr=*/true); case tok::r_paren: case tok::r_square: case tok::l_brace: diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp index 5b5a326c5a5a4..7c69eccc3dcf9 100644 --- a/lib/Sema/CSDiagnostics.cpp +++ b/lib/Sema/CSDiagnostics.cpp @@ -9360,7 +9360,16 @@ bool InvalidMemberReferenceWithinInitAccessor::diagnoseAsError() { } bool ConcreteTypeSpecialization::diagnoseAsError() { - emitDiagnostic(diag::not_a_generic_type, ConcreteType); + if (isa(Decl)) { + emitDiagnostic(diag::not_a_generic_macro, Decl); + } else { + emitDiagnostic(diag::not_a_generic_type, ConcreteType); + } + return true; +} + +bool GenericFunctionSpecialization::diagnoseAsError() { + emitDiagnostic(diag::cannot_explicitly_specialize_generic_function); return true; } diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h index 4d4c81ce2b0fa..06cddcd77fdec 100644 --- a/lib/Sema/CSDiagnostics.h +++ b/lib/Sema/CSDiagnostics.h @@ -3127,12 +3127,25 @@ class InvalidMemberReferenceWithinInitAccessor final /// \endcode class ConcreteTypeSpecialization final : public FailureDiagnostic { Type ConcreteType; + ValueDecl *Decl; public: ConcreteTypeSpecialization(const Solution &solution, Type concreteTy, - ConstraintLocator *locator) - : FailureDiagnostic(solution, locator), - ConcreteType(resolveType(concreteTy)) {} + ValueDecl *decl, ConstraintLocator *locator, + FixBehavior fixBehavior) + : FailureDiagnostic(solution, locator, fixBehavior), + ConcreteType(resolveType(concreteTy)), Decl(decl) {} + + bool diagnoseAsError() override; +}; + +class GenericFunctionSpecialization final : public FailureDiagnostic { + ValueDecl *Decl; + +public: + GenericFunctionSpecialization(const Solution &solution, ValueDecl *decl, + ConstraintLocator *locator) + : FailureDiagnostic(solution, locator), Decl(decl) {} bool diagnoseAsError() override; }; diff --git a/lib/Sema/CSFix.cpp b/lib/Sema/CSFix.cpp index 7bda044857a54..d35f843f2aa30 100644 --- a/lib/Sema/CSFix.cpp +++ b/lib/Sema/CSFix.cpp @@ -2605,15 +2605,28 @@ AllowInvalidMemberReferenceInInitAccessor::create(ConstraintSystem &cs, bool AllowConcreteTypeSpecialization::diagnose(const Solution &solution, bool asNote) const { - ConcreteTypeSpecialization failure(solution, ConcreteType, getLocator()); + ConcreteTypeSpecialization failure(solution, ConcreteType, Decl, getLocator(), + fixBehavior); return failure.diagnose(asNote); } -AllowConcreteTypeSpecialization * -AllowConcreteTypeSpecialization::create(ConstraintSystem &cs, Type concreteTy, - ConstraintLocator *locator) { +AllowConcreteTypeSpecialization *AllowConcreteTypeSpecialization::create( + ConstraintSystem &cs, Type concreteTy, ValueDecl *decl, + ConstraintLocator *locator, FixBehavior fixBehavior) { + return new (cs.getAllocator()) AllowConcreteTypeSpecialization( + cs, concreteTy, decl, locator, fixBehavior); +} + +bool AllowGenericFunctionSpecialization::diagnose(const Solution &solution, + bool asNote) const { + GenericFunctionSpecialization failure(solution, Decl, getLocator()); + return failure.diagnose(asNote); +} + +AllowGenericFunctionSpecialization *AllowGenericFunctionSpecialization::create( + ConstraintSystem &cs, ValueDecl *decl, ConstraintLocator *locator) { return new (cs.getAllocator()) - AllowConcreteTypeSpecialization(cs, concreteTy, locator); + AllowGenericFunctionSpecialization(cs, decl, locator); } bool IgnoreOutOfPlaceThenStmt::diagnose(const Solution &solution, diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 4397d9b7139d0..4b972a62bb2b8 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1903,9 +1903,9 @@ namespace { /// introduce them as an explicit generic arguments constraint. /// /// \returns true if resolving any of the specialization types failed. - bool addSpecializationConstraint( - ConstraintLocator *locator, Type boundType, - ArrayRef specializationArgs) { + void addSpecializationConstraint(ConstraintLocator *locator, Type boundType, + SourceLoc lAngleLoc, + ArrayRef specializationArgs) { // Resolve each type. SmallVector specializationArgTypes; auto options = @@ -1916,61 +1916,35 @@ namespace { options |= TypeResolutionFlags::AllowPackReferences; elementEnv = OuterExpansions.back(); } - const auto result = TypeResolution::resolveContextualType( + auto result = TypeResolution::resolveContextualType( specializationArg, CurDC, options, // Introduce type variables for unbound generics. OpenUnboundGenericType(CS, locator), HandlePlaceholderType(CS, locator), OpenPackElementType(CS, locator, elementEnv)); - if (result->hasError()) - return true; - + if (result->hasError()) { + auto &ctxt = CS.getASTContext(); + result = PlaceholderType::get(ctxt, specializationArg); + ctxt.Diags.diagnose(lAngleLoc, + diag::while_parsing_as_left_angle_bracket); + } specializationArgTypes.push_back(result); } - CS.addConstraint( - ConstraintKind::ExplicitGenericArguments, boundType, - PackType::get(CS.getASTContext(), specializationArgTypes), - locator); - return false; + auto constraint = Constraint::create( + CS, ConstraintKind::ExplicitGenericArguments, boundType, + PackType::get(CS.getASTContext(), specializationArgTypes), locator); + CS.addUnsolvedConstraint(constraint); + CS.activateConstraint(constraint); } Type visitUnresolvedSpecializeExpr(UnresolvedSpecializeExpr *expr) { auto baseTy = CS.getType(expr->getSubExpr()); - - if (baseTy->isTypeVariableOrMember()) { - return baseTy; - } - - // We currently only support explicit specialization of generic types. - // FIXME: We could support explicit function specialization. - auto &de = CS.getASTContext().Diags; - if (baseTy->is()) { - de.diagnose(expr->getSubExpr()->getLoc(), - diag::cannot_explicitly_specialize_generic_function); - de.diagnose(expr->getLAngleLoc(), - diag::while_parsing_as_left_angle_bracket); - return Type(); - } - - if (AnyMetatypeType *meta = baseTy->getAs()) { - auto *overloadLocator = CS.getConstraintLocator(expr->getSubExpr()); - if (addSpecializationConstraint(overloadLocator, - meta->getInstanceType(), - expr->getUnresolvedParams())) { - return Type(); - } - - return baseTy; - } - - // FIXME: If the base type is a type variable, constrain it to a metatype - // of a bound generic type. - de.diagnose(expr->getSubExpr()->getLoc(), - diag::not_a_generic_definition); - de.diagnose(expr->getLAngleLoc(), - diag::while_parsing_as_left_angle_bracket); - return Type(); + auto *overloadLocator = CS.getConstraintLocator(expr->getSubExpr()); + addSpecializationConstraint( + overloadLocator, baseTy->getMetatypeInstanceType(), + expr->getLAngleLoc(), expr->getUnresolvedParams()); + return baseTy; } Type visitSequenceExpr(SequenceExpr *expr) { @@ -4080,10 +4054,9 @@ namespace { // Add explicit generic arguments, if there were any. if (expr->getGenericArgsRange().isValid()) { - if (addSpecializationConstraint( - CS.getConstraintLocator(expr), macroRefType, - expr->getGenericArgs())) - return Type(); + addSpecializationConstraint(CS.getConstraintLocator(expr), macroRefType, + expr->getGenericArgsRange().Start, + expr->getGenericArgs()); } // Form the applicable-function constraint. The result type @@ -4828,11 +4801,11 @@ bool ConstraintSystem::generateConstraints( // If we have a placeholder originating from a PlaceholderTypeRepr, // tack that on to the locator. if (auto *placeholderTy = ty->getAs()) - if (auto *placeholderRepr = placeholderTy->getOriginator() - .dyn_cast()) + if (auto *typeRepr = placeholderTy->getOriginator() + .dyn_cast()) return getConstraintLocator( convertTypeLocator, - LocatorPathElt::PlaceholderType(placeholderRepr)); + LocatorPathElt::PlaceholderType(typeRepr)); return convertTypeLocator; }; diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 8592aa2b491b4..318bf82a9d5bd 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -13950,6 +13950,8 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint( // Bail out if we haven't selected an overload yet. auto simplifiedBoundType = simplifyType(type1, flags); + if (simplifiedBoundType->isPlaceholder()) + return SolutionKind::Solved; if (simplifiedBoundType->isTypeVariableOrMember()) return formUnsolved(); @@ -14042,13 +14044,15 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint( } } - if (!decl->getAsGenericContext()) - return SolutionKind::Error; - auto genericParams = getGenericParams(decl); - if (!genericParams) { - // FIXME: Record an error here that we're ignoring the parameters. - return SolutionKind::Solved; + if (!decl->getAsGenericContext() || !genericParams) { + // Allow concrete macros to have specializations with just a warning. + return recordFix(AllowConcreteTypeSpecialization::create( + *this, type1, decl, getConstraintLocator(locator), + isa(decl) ? FixBehavior::DowngradeToWarning + : FixBehavior::Error)) + ? SolutionKind::Error + : SolutionKind::Solved; } // Map the generic parameters we have over to their opened types. @@ -14081,12 +14085,14 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint( } } - if (openedGenericParams.empty()) { + // FIXME: We could support explicit function specialization. + if (openedGenericParams.empty() || + (isa(decl) && !hasParameterPack)) { if (!shouldAttemptFixes()) return SolutionKind::Error; - return recordFix(AllowConcreteTypeSpecialization::create( - *this, type1, getConstraintLocator(locator))) + return recordFix(AllowGenericFunctionSpecialization::create( + *this, decl, getConstraintLocator(locator))) ? SolutionKind::Error : SolutionKind::Solved; } @@ -15217,6 +15223,7 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyFixConstraint( case FixKind::AllowAssociatedValueMismatch: case FixKind::GenericArgumentsMismatch: case FixKind::AllowConcreteTypeSpecialization: + case FixKind::AllowGenericFunctionSpecialization: case FixKind::IgnoreGenericSpecializationArityMismatch: case FixKind::IgnoreKeyPathSubscriptIndexMismatch: case FixKind::AllowMemberRefOnExistential: { diff --git a/lib/Sema/ConstraintSystem.cpp b/lib/Sema/ConstraintSystem.cpp index da599475a36a4..b422268624c69 100644 --- a/lib/Sema/ConstraintSystem.cpp +++ b/lib/Sema/ConstraintSystem.cpp @@ -1077,17 +1077,17 @@ Type ConstraintSystem::replaceInferableTypesWithTypeVars( return openUnboundGenericType(unbound->getDecl(), unbound->getParent(), locator, /*isTypeResolution=*/false); } else if (auto *placeholderTy = type->getAs()) { - if (auto *placeholderRepr = placeholderTy->getOriginator() - .dyn_cast()) { - - return createTypeVariable( - getConstraintLocator( - locator, LocatorPathElt::PlaceholderType(placeholderRepr)), - TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding | - TVO_CanBindToHole); - } - - if (auto *var = placeholderTy->getOriginator().dyn_cast()) { + if (auto *typeRepr = + placeholderTy->getOriginator().dyn_cast()) { + if (isa(typeRepr)) { + return createTypeVariable( + getConstraintLocator(locator, + LocatorPathElt::PlaceholderType(typeRepr)), + TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding | + TVO_CanBindToHole); + } + } else if (auto *var = + placeholderTy->getOriginator().dyn_cast()) { if (var->getName().hasDollarPrefix()) { auto *repr = new (type->getASTContext()) PlaceholderTypeRepr(var->getLoc()); diff --git a/lib/Sema/TypeCheckDeclPrimary.cpp b/lib/Sema/TypeCheckDeclPrimary.cpp index 4573e0cb4d2cb..c86ccd039a944 100644 --- a/lib/Sema/TypeCheckDeclPrimary.cpp +++ b/lib/Sema/TypeCheckDeclPrimary.cpp @@ -1171,7 +1171,8 @@ void TypeChecker::notePlaceholderReplacementTypes(Type writtenType, } if (auto *origRepr = - placeholder->getOriginator().dyn_cast()) { + placeholder->getOriginator().dyn_cast()) { + assert(isa(origRepr)); t1->getASTContext() .Diags .diagnose(origRepr->getLoc(), diff --git a/test/Constraints/ambiguous_specialized_name_diagnostics.swift b/test/Constraints/ambiguous_specialized_name_diagnostics.swift index 322d004ed308c..90d363b8f1e88 100644 --- a/test/Constraints/ambiguous_specialized_name_diagnostics.swift +++ b/test/Constraints/ambiguous_specialized_name_diagnostics.swift @@ -42,7 +42,6 @@ func test() { S(t: 42).test() // expected-error {{ambiguous use of 'init(t:)'}} - // FIXME(diagnostics): This should produce ambiguity diagnostic too S.staticFn() - // expected-error@-1 {{generic parameter 'T' could not be inferred}} + // expected-error@-1 {{ambiguous use of 'staticFn()'}} } diff --git a/test/Macros/attached_macros_diags.swift b/test/Macros/attached_macros_diags.swift index f084d47a201c3..85749424190ae 100644 --- a/test/Macros/attached_macros_diags.swift +++ b/test/Macros/attached_macros_diags.swift @@ -69,4 +69,8 @@ struct TestMacroArgs { // expected-error@-1{{missing argument for parameter #1 in macro expansion}} @m3(message: #stringify(Nested.x).1) struct Args8 {} + + // Allow macros to have arbitrary generic specialization lists, but warn + // https://github.com/swiftlang/swift/issues/75500 + @m1 struct Args9 {} // expected-warning {{cannot specialize a non-generic external macro 'm1()'}} } diff --git a/test/Parse/enum_element_pattern_swift4.swift b/test/Parse/enum_element_pattern_swift4.swift index 942f10420be94..4cdbea06d6f45 100644 --- a/test/Parse/enum_element_pattern_swift4.swift +++ b/test/Parse/enum_element_pattern_swift4.swift @@ -9,10 +9,13 @@ enum E { static func testE(e: E) { switch e { - case A(): // expected-error {{cannot specialize a non-generic definition}} + case A(): // expected-error {{cannot find type 'UndefinedTy' in scope}} // expected-note@-1 {{while parsing this '<' as a type parameter bracket}} + // expected-error@-2 {{cannot specialize non-generic type 'E'}} + // expected-error@-3 {{cannot call value of non-function type 'E'}} break - case B(): // expected-error {{cannot specialize a non-generic definition}} expected-note {{while parsing this '<' as a type parameter bracket}} + case B(): // expected-error {{cannot specialize non-generic type 'E'}} + // expected-error@-1 {{cannot call value of non-function type 'E'}} break default: break; @@ -22,10 +25,13 @@ enum E { func testE(e: E) { switch e { - case E.A(): // expected-error {{cannot specialize a non-generic definition}} + case E.A(): // expected-error {{cannot find type 'UndefinedTy' in scope}} // expected-note@-1 {{while parsing this '<' as a type parameter bracket}} + // expected-error@-2 {{cannot specialize non-generic type 'E'}} + // expected-error@-3 {{cannot call value of non-function type 'E'}} break - case E.B(): // expected-error {{cannot specialize a non-generic definition}} expected-note {{while parsing this '<' as a type parameter bracket}} + case E.B(): // expected-error {{cannot specialize non-generic type 'E'}} + // expected-error@-1 {{cannot call value of non-function type 'E'}} break case .C(): // expected-error {{pattern with associated values does not match enum case 'C'}} // expected-note@-1 {{remove associated values to make the pattern match}} {{10-12=}} diff --git a/test/Parse/generic_disambiguation.swift b/test/Parse/generic_disambiguation.swift index ebb900e3e8c47..e93d26f4a4efe 100644 --- a/test/Parse/generic_disambiguation.swift +++ b/test/Parse/generic_disambiguation.swift @@ -26,15 +26,21 @@ var a, b, c, d : Int _ = a < b _ = (a < b, c > d) // Parses as generic because of lparen after '>' -(a < b, c > (d)) // expected-error{{cannot specialize a non-generic definition}} -// expected-note@-1 {{while parsing this '<' as a type parameter bracket}} +(a < b, c > (d)) // expected-error{{cannot find type 'b' in scope}} +// expected-note@-1 2 {{while parsing this '<' as a type parameter bracket}} +// expected-error@-2 {{cannot specialize non-generic type 'Int'}} +// expected-error@-3 {{cannot call value of non-function type 'Int'}} +// expected-error@-4 {{cannot find type 'c' in scope}} // Parses as generic because of lparen after '>' -(a(d)) // expected-error{{cannot specialize a non-generic definition}} -// expected-note@-1 {{while parsing this '<' as a type parameter bracket}} +(a(d)) // expected-error{{cannot find type 'b' in scope}} +// expected-note@-1 2 {{while parsing this '<' as a type parameter bracket}} +// expected-error@-2 {{cannot specialize non-generic type 'Int'}} +// expected-error@-3 {{cannot call value of non-function type 'Int'}} +// expected-error@-4 {{cannot find type 'c' in scope}} _ = a>(b) _ = a > (b) -generic(0) // expected-error{{cannot explicitly specialize a generic function}} expected-note{{while parsing this '<' as a type parameter bracket}} +generic(0) // expected-error{{cannot explicitly specialize a generic function}} A.c() A>.c() diff --git a/test/Sema/generic-arg-list.swift b/test/Sema/generic-arg-list.swift new file mode 100644 index 0000000000000..04e7c1c24cf75 --- /dev/null +++ b/test/Sema/generic-arg-list.swift @@ -0,0 +1,41 @@ +// RUN: %target-typecheck-verify-swift + +extension Int { + func foo() -> Int {} + var bar: Int { + get {} + } + + func baz() -> Int {} + func baz(_ x: Int = 0) -> Int {} + + func gen() -> T {} // expected-note 2 {{in call to function 'gen()'}} +} + +// https://github.com/swiftlang/swift/issues/74857 +func test(i: Int) { + let _ = i.foo() // expected-error {{cannot specialize non-generic type '() -> Int'}} + + let _ = i.gen() // expected-error {{cannot explicitly specialize a generic function}} + // expected-error@-1 {{generic parameter 'T' could not be inferred}} + + let _ = 0.foo() // expected-error {{cannot specialize non-generic type '() -> Int'}} + + let _ = i.gen // expected-error {{cannot explicitly specialize a generic function}} + // expected-error@-1 {{generic parameter 'T' could not be inferred}} + let _ = i.bar // expected-error {{cannot specialize non-generic type 'Int'}} + let _ = 0.bar // expected-error {{cannot specialize non-generic type 'Int'}} +} + +extension Bool { + func foo() -> T {} +} + +let _: () -> Bool = false.foo // expected-error {{cannot explicitly specialize a generic function}} + +func foo(_ x: Int) { + _ = { + _ = x // expected-error {{cannot specialize non-generic type 'Int'}} + } +} +