mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Sema: Ban shadowing generic parameters from outer scopes
Code like that is usually indicative of programmer error, and does not round-trip through module interface files since there is no source syntax to refer to an outer generic parameter. For source compatibility this is a warning, but becomes an error with -swift-version 6. Fixes rdar://problem/108385980 and https://github.com/apple/swift/issues/62767.
This commit is contained in:
@@ -2783,6 +2783,10 @@ ERROR(requires_generic_params_made_equal,none,
|
||||
ERROR(requires_generic_param_made_equal_to_concrete,none,
|
||||
"same-type requirement makes generic parameter %0 non-generic",
|
||||
(Type))
|
||||
ERROR(shadowed_generic_param,none,
|
||||
"generic parameter %0 shadows generic parameter from outer scope with the same name",
|
||||
(DeclName))
|
||||
|
||||
ERROR(recursive_decl_reference,none,
|
||||
"%0 %1 references itself", (DescriptiveDeclKind, DeclBaseName))
|
||||
ERROR(recursive_generic_signature,none,
|
||||
|
||||
@@ -454,11 +454,10 @@ static void diagnoseDuplicateDecls(T &&decls) {
|
||||
other->diagnose(diag::invalid_redecl_prev, other->getName());
|
||||
});
|
||||
|
||||
// Mark the decl as invalid, unless it's a GenericTypeParamDecl, which is
|
||||
// expected to maintain its type of GenericTypeParamType.
|
||||
// This is needed to avoid emitting a duplicate diagnostic when running
|
||||
// redeclaration checking in the case where the VarDecl is part of the
|
||||
// enclosing context, e.g `let (x, x) = (0, 0)`.
|
||||
// Mark the decl as invalid. This is needed to avoid emitting a
|
||||
// duplicate diagnostic when running redeclaration checking in
|
||||
// the case where the VarDecl is part of the enclosing context,
|
||||
// e.g `let (x, x) = (0, 0)`.
|
||||
if (!isa<GenericTypeParamDecl>(current))
|
||||
current->setInvalid();
|
||||
}
|
||||
@@ -492,7 +491,7 @@ static void checkGenericParams(GenericContext *ownerCtx) {
|
||||
[](Requirement, RequirementRepr *) { return false; });
|
||||
|
||||
// Check for duplicate generic parameter names.
|
||||
diagnoseDuplicateDecls(*genericParams);
|
||||
TypeChecker::checkShadowedGenericParams(ownerCtx);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
||||
@@ -498,6 +498,63 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensure we don't re-declare any generic parameters in the current scope,
|
||||
/// or shadow a generic parameter from an outer scope.
|
||||
void TypeChecker::checkShadowedGenericParams(GenericContext *dc) {
|
||||
// Collect all outer generic parameters for lookup.
|
||||
llvm::SmallDenseMap<Identifier, GenericTypeParamDecl *, 4> genericParamDecls;
|
||||
for (auto *parentDC = dc->getParent(); parentDC != nullptr;
|
||||
parentDC = parentDC->getParentForLookup()) {
|
||||
if (auto *extensionDecl = dyn_cast<ExtensionDecl>(parentDC)) {
|
||||
parentDC = extensionDecl->getExtendedNominal();
|
||||
|
||||
// This can happen with invalid code.
|
||||
if (parentDC == nullptr)
|
||||
return;
|
||||
}
|
||||
if (auto *parentDecl = parentDC->getAsDecl()) {
|
||||
if (auto *parentGeneric = parentDecl->getAsGenericContext()) {
|
||||
if (auto *genericParamList = parentGeneric->getGenericParams()) {
|
||||
for (auto *genericParamDecl : genericParamList->getParams()) {
|
||||
if (genericParamDecl->isOpaqueType())
|
||||
continue;
|
||||
genericParamDecls[genericParamDecl->getName()] = genericParamDecl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto *genericParamDecl : dc->getGenericParams()->getParams()) {
|
||||
if (genericParamDecl->isOpaqueType() || genericParamDecl->isImplicit())
|
||||
continue;
|
||||
|
||||
auto found = genericParamDecls.find(genericParamDecl->getName());
|
||||
if (found != genericParamDecls.end()) {
|
||||
auto *existingParamDecl = found->second;
|
||||
|
||||
if (existingParamDecl->getDeclContext() == dc) {
|
||||
genericParamDecl->diagnose(
|
||||
diag::invalid_redecl,
|
||||
genericParamDecl->getName());
|
||||
} else {
|
||||
genericParamDecl->diagnose(
|
||||
diag::shadowed_generic_param,
|
||||
genericParamDecl->getName()).warnUntilSwiftVersion(6);
|
||||
}
|
||||
|
||||
if (existingParamDecl->getLoc()) {
|
||||
existingParamDecl->diagnose(diag::invalid_redecl_prev,
|
||||
existingParamDecl->getName());
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
genericParamDecls[genericParamDecl->getName()] = genericParamDecl;
|
||||
}
|
||||
}
|
||||
|
||||
///
|
||||
/// Generic types
|
||||
///
|
||||
|
||||
@@ -500,6 +500,10 @@ void checkProtocolSelfRequirements(ValueDecl *decl);
|
||||
/// declaration's type, otherwise we have no way to infer them.
|
||||
void checkReferencedGenericParams(GenericContext *dc);
|
||||
|
||||
/// Ensure we don't re-declare any generic parameters in the current scope,
|
||||
/// or shadow a generic parameter from an outer scope.
|
||||
void checkShadowedGenericParams(GenericContext *dc);
|
||||
|
||||
/// Diagnose a requirement failure.
|
||||
///
|
||||
/// \param errorLoc The location at which an error shall be emitted.
|
||||
|
||||
@@ -496,7 +496,7 @@ extension Struct {
|
||||
}
|
||||
|
||||
// expected-note @+1 {{candidate subscript does not have a setter}}
|
||||
subscript<T: Differentiable>(x: T) -> T { x }
|
||||
subscript<U: Differentiable>(x: U) -> U { x }
|
||||
}
|
||||
extension Struct where T: Differentiable & AdditiveArithmetic {
|
||||
@derivative(of: subscript.get)
|
||||
@@ -534,14 +534,14 @@ extension Struct where T: Differentiable & AdditiveArithmetic {
|
||||
}
|
||||
|
||||
@derivative(of: subscript(_:).get, wrt: self)
|
||||
func vjpSubscriptGenericGetter<T: Differentiable>(x: T) -> (value: T, pullback: (T.TangentVector) -> TangentVector) {
|
||||
func vjpSubscriptGenericGetter<U: Differentiable>(x: U) -> (value: U, pullback: (U.TangentVector) -> TangentVector) {
|
||||
return (x, { _ in .zero })
|
||||
}
|
||||
|
||||
// expected-error @+2 {{a derivative already exists for '_'}}
|
||||
// expected-note @-6 {{other attribute declared here}}
|
||||
@derivative(of: subscript(_:), wrt: self)
|
||||
func vjpSubscriptGeneric<T: Differentiable>(x: T) -> (value: T, pullback: (T.TangentVector) -> TangentVector) {
|
||||
func vjpSubscriptGeneric<U: Differentiable>(x: U) -> (value: U, pullback: (U.TangentVector) -> TangentVector) {
|
||||
return (x, { _ in .zero })
|
||||
}
|
||||
|
||||
@@ -576,8 +576,8 @@ extension Struct where T: Differentiable & AdditiveArithmetic {
|
||||
// Error: original subscript has no setter.
|
||||
// expected-error @+1 {{referenced declaration 'subscript(_:)' could not be resolved}}
|
||||
@derivative(of: subscript(_:).set, wrt: self)
|
||||
mutating func vjpSubscriptGeneric_NoSetter<T: Differentiable>(x: T) -> (
|
||||
value: T, pullback: (T.TangentVector) -> TangentVector
|
||||
mutating func vjpSubscriptGeneric_NoSetter<U: Differentiable>(x: U) -> (
|
||||
value: U, pullback: (U.TangentVector) -> TangentVector
|
||||
) {
|
||||
return (x, { _ in .zero })
|
||||
}
|
||||
|
||||
@@ -516,8 +516,8 @@ public struct PublicGenericIPReq<T: InternalProto> where T: PrivateProto {} // e
|
||||
|
||||
public func genericFunc<T: InternalProto>(_: T) {} // expected-error {{function cannot be declared public because its generic parameter uses an internal type}} {}
|
||||
public class GenericClass<T: InternalProto> { // expected-error {{generic class cannot be declared public because its generic parameter uses an internal type}}
|
||||
public init<T: PrivateProto>(_: T) {} // expected-error {{initializer cannot be declared public because its generic parameter uses a private type}}
|
||||
public func genericMethod<T: PrivateProto>(_: T) {} // expected-error {{instance method cannot be declared public because its generic parameter uses a private type}}
|
||||
public init<U: PrivateProto>(_: U) {} // expected-error {{initializer cannot be declared public because its generic parameter uses a private type}}
|
||||
public func genericMethod<U: PrivateProto>(_: U) {} // expected-error {{instance method cannot be declared public because its generic parameter uses a private type}}
|
||||
}
|
||||
public enum GenericEnum<T: InternalProto> { // expected-error {{generic enum cannot be declared public because its generic parameter uses an internal type}}
|
||||
case A
|
||||
|
||||
@@ -508,11 +508,12 @@ public struct S5 {
|
||||
|
||||
// rdar://problem/24329052 - QoI: call argument archetypes not lining up leads to ambiguity errors
|
||||
|
||||
struct S_24329052<T> { // expected-note {{generic parameter 'T' of generic struct 'S_24329052' declared here}}
|
||||
struct S_24329052<T> { // expected-note {{generic parameter 'T' of generic struct 'S_24329052' declared here}} expected-note {{'T' previously declared here}}
|
||||
var foo: (T) -> Void
|
||||
// expected-note@+1 {{generic parameter 'T' of instance method 'bar(_:)' declared here}}
|
||||
func bar<T>(_ v: T) { foo(v) }
|
||||
// expected-error@-1 {{cannot convert value of type 'T' (generic parameter of instance method 'bar(_:)') to expected argument type 'T' (generic parameter of generic struct 'S_24329052')}}
|
||||
// expected-warning@-2 {{generic parameter 'T' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
}
|
||||
|
||||
extension Sequence {
|
||||
@@ -943,7 +944,7 @@ do {
|
||||
struct Outer<T: P_eaf0300ff7a> {
|
||||
struct Inner<U> {}
|
||||
|
||||
func container<T>() -> Inner<T> {
|
||||
func container<V>() -> Inner<V> {
|
||||
return Inner()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ final class ViewController<T> {
|
||||
|
||||
extension ViewController: ViewDataSource where T == String {
|
||||
// expected-note@-1 {{requirement from conditional conformance of 'ViewController<T>' to 'ViewDataSource'}}
|
||||
func foo<T>() -> [T] {
|
||||
func foo<U>() -> [U] {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,8 +553,8 @@ func rdar_48114578() {
|
||||
struct S<T> {
|
||||
var value: T
|
||||
|
||||
static func valueOf<T>(_ v: T) -> S<T> {
|
||||
return S<T>(value: v)
|
||||
static func valueOf<U>(_ v: U) -> S<U> {
|
||||
return S<U>(value: v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -219,8 +219,8 @@ do {
|
||||
}
|
||||
|
||||
do {
|
||||
func testRef<each T>() -> (repeat each T, String) { fatalError() }
|
||||
func testResult<each T>() -> (repeat each T) { fatalError() }
|
||||
func testRef<each U>() -> (repeat each U, String) { fatalError() }
|
||||
func testResult<each U>() -> (repeat each U) { fatalError() }
|
||||
|
||||
func experiment1<each U>() -> (repeat each U, String) {
|
||||
testResult() // Ok
|
||||
|
||||
@@ -43,7 +43,7 @@ class X<T> {
|
||||
}
|
||||
|
||||
class Y<U> : X<Int> {
|
||||
func otherMethod<U>(_ x: Int, y: U) {
|
||||
func otherMethod<V>(_ x: Int, y: V) {
|
||||
super.method(x, y: y)
|
||||
}
|
||||
}
|
||||
|
||||
17
test/Generics/shadowed_generic_params.swift
Normal file
17
test/Generics/shadowed_generic_params.swift
Normal file
@@ -0,0 +1,17 @@
|
||||
// RUN: %target-typecheck-verify-swift
|
||||
|
||||
struct Outer<T, U> { // expected-note 2{{'T' previously declared here}}
|
||||
struct Inner<V> { // expected-note 2{{'V' previously declared here}}
|
||||
func foo<T>(_: T) {} // expected-warning {{generic parameter 'T' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
func bar<V>(_: V) {} // expected-warning {{generic parameter 'V' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
}
|
||||
}
|
||||
|
||||
extension Outer.Inner {
|
||||
func baz<T>(_: T) {} // expected-warning {{generic parameter 'T' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
func quux<V>(_: V) {} // expected-warning {{generic parameter 'V' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
}
|
||||
|
||||
extension Sequence {
|
||||
func bing<Self>(_: Self) {} // expected-warning {{generic parameter 'Self' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
}
|
||||
@@ -935,9 +935,9 @@ package struct PackageGenericIPReq<T: InternalProto> where T: PrivateProto {} //
|
||||
public func genericFunc<T: InternalProto>(_: T) {} // expected-error {{function cannot be declared public because its generic parameter uses an internal type}} {}
|
||||
public func genericFuncPackage<T: PackageProto>(_: T) {} // expected-error {{function cannot be declared public because its generic parameter uses a package type}} {}
|
||||
public class GenericClass<T: InternalProto> { // expected-error {{generic class cannot be declared public because its generic parameter uses an internal type}}
|
||||
public init<T: PrivateProto>(_: T) {} // expected-error {{initializer cannot be declared public because its generic parameter uses a private type}}
|
||||
public func genericMethod<T: PrivateProto>(_: T) {} // expected-error {{instance method cannot be declared public because its generic parameter uses a private type}}
|
||||
public func genericMethodPackage<T: PackageProto>(_: T) {} // expected-error {{instance method cannot be declared public because its generic parameter uses a package type}}
|
||||
public init<U: PrivateProto>(_: U) {} // expected-error {{initializer cannot be declared public because its generic parameter uses a private type}}
|
||||
public func genericMethod<U: PrivateProto>(_: U) {} // expected-error {{instance method cannot be declared public because its generic parameter uses a private type}}
|
||||
public func genericMethodPackage<U: PackageProto>(_: U) {} // expected-error {{instance method cannot be declared public because its generic parameter uses a package type}}
|
||||
}
|
||||
public enum GenericEnum<T: InternalProto> { // expected-error {{generic enum cannot be declared public because its generic parameter uses an internal type}}
|
||||
case A
|
||||
@@ -948,8 +948,8 @@ public enum GenericEnumPackage<T: PackageProto> { // expected-error {{generic en
|
||||
|
||||
package func packageGenericFunc<T: InternalProto>(_: T) {} // expected-error {{function cannot be declared package because its generic parameter uses an internal type}} {}
|
||||
package class PackageGenericClassT<T: InternalProto> { // expected-error {{generic class cannot be declared package because its generic parameter uses an internal type}}
|
||||
package init<T: PrivateProto>(_: T) {} // expected-error {{initializer cannot be declared package because its generic parameter uses a private type}}
|
||||
package func packageGenericMethod<T: PrivateProto>(_: T) {} // expected-error {{instance method cannot be declared package because its generic parameter uses a private type}}
|
||||
package init<U: PrivateProto>(_: U) {} // expected-error {{initializer cannot be declared package because its generic parameter uses a private type}}
|
||||
package func packageGenericMethod<U: PrivateProto>(_: U) {} // expected-error {{instance method cannot be declared package because its generic parameter uses a private type}}
|
||||
}
|
||||
package enum PackageGenericEnumT<T: InternalProto> { // expected-error {{generic enum cannot be declared package because its generic parameter uses an internal type}}
|
||||
case A
|
||||
|
||||
@@ -39,7 +39,7 @@ enum Maybe<T> {
|
||||
}
|
||||
|
||||
struct CerebralValley<T> {
|
||||
struct GenericBro<T> {}
|
||||
struct GenericBro<U> {}
|
||||
struct TechBro {}
|
||||
}
|
||||
|
||||
|
||||
@@ -516,7 +516,7 @@ protocol Protocol2 {}
|
||||
// Base class is generic, derived class is concrete.
|
||||
|
||||
class Base1<T> {
|
||||
func foo<T: Protocol1>(arg: T) {}
|
||||
func foo<U: Protocol1>(arg: U) {}
|
||||
}
|
||||
class Derived1: Base1<Protocol2> {
|
||||
override func foo<T>(arg: T) {} // Ok?
|
||||
@@ -528,14 +528,14 @@ class Base2 {
|
||||
func foo() {}
|
||||
}
|
||||
class Derived2<T>: Base2 {
|
||||
override func foo<T>(arg: T) {} // expected-error {{method does not override any method from its superclass}}
|
||||
override func foo<U>(arg: U) {} // expected-error {{method does not override any method from its superclass}}
|
||||
}
|
||||
|
||||
// Base class generic w/ method generic, derived class generic w/ method not
|
||||
// generic.
|
||||
|
||||
class Base3<T> {
|
||||
func foo<T>(arg: T) {}
|
||||
func foo<U>(arg: U) {}
|
||||
}
|
||||
class Derived3<T>: Base3<T> {
|
||||
override func foo() {} // expected-error {{method does not override any method from its superclass}}
|
||||
@@ -545,10 +545,10 @@ class Derived3<T>: Base3<T> {
|
||||
// but different requirement.
|
||||
|
||||
class Base4<T> {
|
||||
func foo<T>(arg: T) {}
|
||||
func foo<U>(arg: U) {}
|
||||
}
|
||||
class Derived4<T>: Base4<T> {
|
||||
override func foo<T: Protocol1>(arg: T) {} // expected-error {{method does not override any method from its superclass}}
|
||||
override func foo<U: Protocol1>(arg: U) {} // expected-error {{method does not override any method from its superclass}}
|
||||
}
|
||||
|
||||
// Base class not generic w/ method generic, derived class not generic w/ method
|
||||
@@ -578,7 +578,7 @@ class Base7 {
|
||||
func foo<T: Protocol2>(arg: T) {}
|
||||
}
|
||||
class Derived7<T>: Base7 {
|
||||
override func foo<T: Protocol1>(arg: T) {} // expected-error {{method does not override any method from its superclass}}
|
||||
override func foo<U: Protocol1>(arg: U) {} // expected-error {{method does not override any method from its superclass}}
|
||||
}
|
||||
|
||||
// Override with orthogonal requirement on contextual generic parameter.
|
||||
|
||||
@@ -175,7 +175,7 @@ struct ConformsToSimpleThrowsClosure<T : RethrowingProtocol> : SimpleThrowsClosu
|
||||
try t.source()
|
||||
}
|
||||
|
||||
func doIt2<T : Empty>(_: T) rethrows {}
|
||||
func doIt2<U : Empty>(_: U) rethrows {}
|
||||
// expected-note@-1 {{candidate is 'rethrows' via a conformance, but the protocol requirement is not from a '@rethrows' protocol}}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ extension X<Int, Double, String> {
|
||||
// expected-error@-1 {{extensions must not contain stored properties}}
|
||||
static let x = 0
|
||||
func f() -> Int {}
|
||||
class C<T> {}
|
||||
class C<W> {}
|
||||
}
|
||||
|
||||
typealias GGG = X<Int, Double, String>
|
||||
|
||||
@@ -4,7 +4,7 @@ struct G<T> {}
|
||||
|
||||
extension G {
|
||||
struct H<U> {
|
||||
func usesBoth<T, U>(t: T, u: U) -> (T, U) {}
|
||||
func usesBoth<T1, U1>(t: T1, u: U1) -> (T1, U1) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -85,8 +85,8 @@ class OuterGenericClass<T> {
|
||||
init(t: T) { super.init(); self.t = t }
|
||||
}
|
||||
|
||||
class InnerGenericClass<U> : OuterGenericClass<U> // expected-error {{type 'InnerGenericClass' cannot be nested in generic function 'genericFunction'}}
|
||||
where U : Racoon, U.Stripes == T {
|
||||
class InnerGenericClass<V> : OuterGenericClass<V> // expected-error {{type 'InnerGenericClass' cannot be nested in generic function 'genericFunction'}}
|
||||
where V : Racoon, V.Stripes == T {
|
||||
let t: T
|
||||
|
||||
init(t: T) { super.init(); self.t = t }
|
||||
@@ -130,7 +130,7 @@ func genericFunction<T>(t: T) {
|
||||
class First : Second<T>.UnknownType { }
|
||||
// expected-error@-1 {{type 'First' cannot be nested in generic function 'genericFunction(t:)'}}
|
||||
// expected-error@-2 {{'UnknownType' is not a member type of generic class 'type_in_function.Second<T>'}}
|
||||
class Second<T> : Second { } // expected-note{{'Second' declared here}}
|
||||
class Second<U> : Second { } // expected-note{{'Second' declared here}}
|
||||
// expected-error@-1 {{type 'Second' cannot be nested in generic function 'genericFunction(t:)'}}
|
||||
// expected-error@-2 {{'Second' inherits from itself}}
|
||||
}
|
||||
|
||||
@@ -106,8 +106,8 @@ class OuterGenericClass<T> {
|
||||
}
|
||||
|
||||
class Middle {
|
||||
class Inner1<T> {}
|
||||
class Inner2<T> : Middle where T: Inner1<Int> {}
|
||||
class Inner1<U> {}
|
||||
class Inner2<U> : Middle where U: Inner1<Int> {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -204,9 +204,9 @@ struct X5<t, u, v> {
|
||||
static func u() {}
|
||||
typealias v = String
|
||||
|
||||
func foo<t>(_ t: t) {
|
||||
let t = t
|
||||
_ = t
|
||||
func foo<w>(_ w: w) {
|
||||
let w = w
|
||||
_ = w
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
struct Struct<T> {
|
||||
class Inner {}
|
||||
struct InnerGeneric<T> {}
|
||||
struct InnerGeneric<U> {}
|
||||
}
|
||||
class Class<T> {}
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ class GenericClass<T> {
|
||||
}
|
||||
|
||||
// Stupid corner case -- underlying type is not dependent
|
||||
typealias NotDependent<T> = Int
|
||||
typealias NotDependent<U> = Int
|
||||
|
||||
func misleadingCode(_: NotDependent<String>) {}
|
||||
}
|
||||
@@ -367,7 +367,7 @@ typealias Id<T> = T
|
||||
extension Id {} // expected-error {{non-nominal type 'Id' cannot be extended}}
|
||||
|
||||
class OuterGeneric<T> {
|
||||
typealias Alias<T> = AnotherGeneric<T>
|
||||
typealias Alias<U> = AnotherGeneric<U>
|
||||
// expected-note@-1 {{generic type 'Alias' declared here}}
|
||||
class InnerNonGeneric : Alias {}
|
||||
// expected-error@-1 {{reference to generic type 'OuterGeneric<T>.Alias' requires arguments in <...>}}
|
||||
|
||||
@@ -13,12 +13,12 @@ struct ActionLookup<Identifier: ActionIdentifier> {
|
||||
}
|
||||
|
||||
@resultBuilder
|
||||
enum ActionLookupBuilder<Identifier: ActionIdentifier> {
|
||||
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> ActionLookup<Identifier> {
|
||||
enum ActionLookupBuilder<Identifier: ActionIdentifier> { // expected-note 3{{'Identifier' previously declared here}}
|
||||
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> ActionLookup<Identifier> { // expected-warning {{generic parameter 'Identifier' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
fatalError()
|
||||
}
|
||||
|
||||
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> [ActionLookup<Identifier>] {
|
||||
static func buildBlock<Identifier: ActionIdentifier>(_ components: [ActionLookup<Identifier>]...) -> [ActionLookup<Identifier>] { // expected-warning {{generic parameter 'Identifier' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
[]
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ enum ActionLookupBuilder<Identifier: ActionIdentifier> {
|
||||
[]
|
||||
}
|
||||
|
||||
static func buildOptional<Identifier: ActionIdentifier>(_ component: [ActionLookup<Identifier>]?) -> [ActionLookup<Identifier>] {
|
||||
static func buildOptional<Identifier: ActionIdentifier>(_ component: [ActionLookup<Identifier>]?) -> [ActionLookup<Identifier>] { // expected-warning {{generic parameter 'Identifier' shadows generic parameter from outer scope with the same name; this is an error in Swift 6}}
|
||||
[]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user