diff --git a/lib/Sema/CSGen.cpp b/lib/Sema/CSGen.cpp index 1c71bf20a74de..753bf532c3c36 100644 --- a/lib/Sema/CSGen.cpp +++ b/lib/Sema/CSGen.cpp @@ -1808,60 +1808,14 @@ namespace { } if (AnyMetatypeType *meta = baseTy->getAs()) { - if (BoundGenericType *bgt - = meta->getInstanceType()->getAs()) { - ArrayRef typeVars = bgt->getGenericArgs(); - auto specializations = expr->getUnresolvedParams(); - - // If we have too many generic arguments, complain. - if (specializations.size() > typeVars.size()) { - de.diagnose(expr->getSubExpr()->getLoc(), - diag::type_parameter_count_mismatch, - bgt->getDecl()->getName(), typeVars.size(), - specializations.size(), - /*too many arguments*/ false, - /*isParameterPack?*/ false) - .highlight( - SourceRange(expr->getLAngleLoc(), expr->getRAngleLoc())); - de.diagnose(bgt->getDecl(), diag::kind_declname_declared_here, - DescriptiveDeclKind::GenericType, - bgt->getDecl()->getName()); - return Type(); - } - - // Bind the specified generic arguments to the type variables in the - // open type. - auto *const locator = CS.getConstraintLocator(expr); - auto options = - TypeResolutionOptions(TypeResolverContext::InExpression); - for (size_t i = 0, e = specializations.size(); i < e; ++i) { - PackExpansionExpr *elementEnv = nullptr; - if (!PackElementEnvironments.empty()) { - options |= TypeResolutionFlags::AllowPackReferences; - elementEnv = PackElementEnvironments.back(); - } - - const auto result = TypeResolution::resolveContextualType( - specializations[i], CS.DC, options, - // Introduce type variables for unbound generics. - OpenUnboundGenericType(CS, locator), - HandlePlaceholderType(CS, locator), - OpenPackElementType(CS, locator, elementEnv)); - if (result->hasError()) - return Type(); - - CS.addConstraint(ConstraintKind::Bind, typeVars[i], result, - locator); - } - - return baseTy; - } else { - de.diagnose(expr->getSubExpr()->getLoc(), diag::not_a_generic_type, - meta->getInstanceType()); - de.diagnose(expr->getLAngleLoc(), - diag::while_parsing_as_left_angle_bracket); + 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 diff --git a/lib/Sema/CSSimplify.cpp b/lib/Sema/CSSimplify.cpp index 77d02761259a9..0b71a72c34edf 100644 --- a/lib/Sema/CSSimplify.cpp +++ b/lib/Sema/CSSimplify.cpp @@ -13493,18 +13493,32 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint( if (simplifiedBoundType->isTypeVariableOrMember()) return formUnsolved(); - // If the overload hasn't been resolved, we can't simplify this constraint. - auto overloadLocator = getCalleeLocator(getConstraintLocator(locator)); - auto selectedOverload = findSelectedOverloadFor(overloadLocator); - if (!selectedOverload) - return formUnsolved(); + ValueDecl *decl; + SmallVector openedTypes; + if (auto *bound = dyn_cast(type1.getPointer())) { + decl = bound->getDecl(); + for (auto argType : bound->getDirectGenericArgs()) { + auto *typeVar = argType->getAs(); + auto *genericParam = typeVar->getImpl().getGenericParameter(); + openedTypes.push_back({genericParam, typeVar}); + } + } else { + // If the overload hasn't been resolved, we can't simplify this constraint. + auto overloadLocator = getCalleeLocator(getConstraintLocator(locator)); + auto selectedOverload = findSelectedOverloadFor(overloadLocator); + if (!selectedOverload) + return formUnsolved(); - auto overloadChoice = selectedOverload->choice; - if (!overloadChoice.isDecl()) { - return SolutionKind::Error; + auto overloadChoice = selectedOverload->choice; + if (!overloadChoice.isDecl()) { + return SolutionKind::Error; + } + + decl = overloadChoice.getDecl(); + auto openedOverloadTypes = getOpenedTypes(overloadLocator); + openedTypes.append(openedOverloadTypes.begin(), openedOverloadTypes.end()); } - auto decl = overloadChoice.getDecl(); auto genericContext = decl->getAsGenericContext(); if (!genericContext) return SolutionKind::Error; @@ -13518,9 +13532,28 @@ ConstraintSystem::simplifyExplicitGenericArgumentsConstraint( // Map the generic parameters we have over to their opened types. SmallVector openedGenericParams; auto genericParamDepth = genericParams->getParams()[0]->getDepth(); - for (const auto &openedType : getOpenedTypes(overloadLocator)) { + for (const auto &openedType : openedTypes) { if (openedType.first->getDepth() == genericParamDepth) { - openedGenericParams.push_back(Type(openedType.second)); + // A generic argument list containing pack references expects + // those packs to be wrapped in pack expansion types. If this + // opened type represents the generic argument for a parameter + // pack, wrap generate the appropriate shape constraints and + // add a pack expansion to the argument list. + if (openedType.first->isParameterPack()) { + auto patternType = openedType.second; + auto *shapeLoc = getConstraintLocator( + locator.withPathElement(ConstraintLocator::PackShape)); + auto *shapeType = createTypeVariable(shapeLoc, + TVO_CanBindToPack | + TVO_CanBindToHole); + addConstraint(ConstraintKind::ShapeOf, + shapeType, patternType, shapeLoc); + + auto *expansion = PackExpansionType::get(patternType, shapeType); + openedGenericParams.push_back(expansion); + } else { + openedGenericParams.push_back(Type(openedType.second)); + } } } assert(openedGenericParams.size() == genericParams->size()); diff --git a/test/Macros/macro_expand_variadic.swift b/test/Macros/macro_expand_variadic.swift index d87992964db6e..851d96f93fd55 100644 --- a/test/Macros/macro_expand_variadic.swift +++ b/test/Macros/macro_expand_variadic.swift @@ -2,18 +2,32 @@ // RUN: %empty-directory(%t) // RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/variadic_macros.swift -g -no-toolchain-stdlib-rpath -// RUN: %target-typecheck-verify-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5 -// RUN: %target-build-swift -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -swift-version 5 +// RUN: %target-typecheck-verify-swift -disable-availability-checking -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) -module-name MacroUser -DTEST_DIAGNOSTICS -swift-version 5 +// RUN: %target-build-swift -Xfrontend -disable-availability-checking -swift-version 5 -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -swift-version 5 // RUN: %target-codesign %t/main // RUN: %target-run %t/main | %FileCheck %s @freestanding(expression) macro print(_ value: repeat each Value) = #externalMacro(module: "MacroDefinition", type: "PrintMacro") +@freestanding(expression) macro Print(_ value: repeat each Value) = #externalMacro(module: "MacroDefinition", type: "PrintMacro") + +struct Print { + init() {} +} + +func testAmbiguity() { + let _ = Print() +} + func testIt() { // CHECK: hello // CHECK: [1, 2, 3, 4, 5] #print("hello", [1, 2, 3, 4, 5]) + // CHECK: hello + // CHECK: [1, 2, 3, 4, 5] + #print("hello", [1, 2, 3, 4, 5]) + // CHECK: world #print("world") } diff --git a/test/decl/typealias/generic.swift b/test/decl/typealias/generic.swift index 3b1e6b4143fb4..c4763e474ab2f 100644 --- a/test/decl/typealias/generic.swift +++ b/test/decl/typealias/generic.swift @@ -2,10 +2,7 @@ struct MyType { // expected-note {{generic type 'MyType' declared here}} // expected-note @-1 {{arguments to generic parameter 'TyB' ('S' and 'Int') are expected to be equal}} - // expected-note @-2 6 {{arguments to generic parameter 'TyA' ('Float' and 'Int') are expected to be equal}} - // expected-note @-3 2 {{arguments to generic parameter 'TyA' ('Float' and 'Double') are expected to be equal}} - // expected-note @-4 2 {{arguments to generic parameter 'TyB' ('Int' and 'Float') are expected to be equal}} - // expected-note @-5 2 {{arguments to generic parameter 'TyB' ('Double' and 'Float') are expected to be equal}} + var a : TyA, b : TyB } @@ -255,23 +252,13 @@ let _: ConcreteStruct.O = ConcreteStruct.O(123) let _: ConcreteStruct.O = ConcreteStruct.O(123) // Qualified lookup of generic typealiases nested inside generic contexts -// -// FIXME marks cases which still don't work correctly, and either produce a -// spurious diagnostic, or are actually invalid and do not diagnose. -// -// This occurs because the constraint solver does the wrong thing with an -// UnresolvedSpecializeExpr applied to a generic typealias. -// -// In the other cases, we manage to fold the UnresolvedSpecializeExpr in the -// precheckExpression() phase, which handles generic typealiases correctly. do { - let x1 = GenericClass.TA(a: 4.0, b: 1) // FIXME - let x2 = GenericClass.TA(a: 1, b: 4.0) // FIXME + let x1 = GenericClass.TA(a: 4.0, b: 1) + let x2 = GenericClass.TA(a: 1, b: 4.0) - // FIXME: Should not diagnose - let _: MyType = x1 // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} - let _: MyType = x2 // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} + let _: MyType = x1 + let _: MyType = x2 } let _ = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} @@ -284,12 +271,11 @@ let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) do { - let x1: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // FIXME - let x2: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) // FIXME + let x1: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) + let x2: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) - // FIXME: Should not diagnose - let _: MyType = x1 // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} - let _: MyType = x2 // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} + let _: MyType = x1 + let _: MyType = x2 } let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} @@ -301,8 +287,8 @@ let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) -let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} -let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) // expected-error {{cannot assign value of type 'MyType' to type 'MyType'}} +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) @@ -313,8 +299,8 @@ let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) -let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot assign value of type 'MyType' to type 'GenericClass.TA' (aka 'MyType')}} -let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) // expected-error {{cannot assign value of type 'MyType' to type 'GenericClass.TA' (aka 'MyType')}} +let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} +let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0) let _: GenericClass.TA = GenericClass.TA(a: 4.0, b: 1) // expected-error {{cannot convert value of type 'Double' to expected argument type 'Int'}} let _: GenericClass.TA = GenericClass.TA(a: 1, b: 4.0)