mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Consider this code:
struct A<T> {
struct B {}
struct C<U> {}
}
Previously:
- getDeclaredType() of 'A.B' would give 'A<T>.B'
- getDeclaredTypeInContext() of 'A.B' would give 'A<T>.B'
- getDeclaredType() of 'A.C' would give 'A<T>.C'
- getDeclaredTypeInContext() of 'A.C' would give 'A<T>.C<U>'
This was causing problems for nested generics. Now, with this change,
- getDeclaredType() of 'A.B' gives 'A.B' (*)
- getDeclaredTypeInContext() of 'A.B' gives 'A<T>.B'
- getDeclaredType() of 'A.C' gives 'A.C' (*)
- getDeclaredTypeInContext() of 'A.C' gives 'A<T>.C<U>'
(Differences marked with (*)).
Also, this change makes these accessors fully lazy. Previously,
only getDeclaredTypeInContext() and getDeclaredIterfaceType()
were lazy, whereas getDeclaredType() was built from validateDecl().
Fix a few spots where the return value wasn't being checked
properly.
These functions return ErrorType if a circularity was detected via
the generic parameter list, or if the extension did not resolve.
They return Type() if the extension cannot be resolved *yet*.
This is pretty subtle, and I'll need to do another pass over
callers of these functions at some point. Many of them should be
moved over to use getSelfInContext(), getSelfOfContext() and
getSelfInterfaceType() instead.
Finally, this patch consolidates logic for diagnosting invalid
nesting of types.
The parser had some code for protocols in bad places and bad things
inside protocols, and Sema had several different bail-outs for
bad things in protocols, nested generic types, and stuff nested
inside protocol extensions.
Combine all of these into a single set of checks in Sema. Note
that we no longer give up early if we find invalid nesting.
Leaving decls unvalidated and un-type-checked only leads to
further problems. Now that all the preliminary crap has been
fixed, we can go ahead and start validating these funny nested
decls, actually fixing some crashers in the process.
125 lines
3.7 KiB
Swift
125 lines
3.7 KiB
Swift
// RUN: %target-parse-verify-swift
|
|
|
|
var func5 : (fn : (Int,Int) -> ()) -> ()
|
|
|
|
// Default arguments for functions.
|
|
func foo3(a: Int = 2, b: Int = 3) {}
|
|
func functionCall() {
|
|
foo3(a: 4)
|
|
foo3()
|
|
foo3(a : 4)
|
|
foo3(b : 4)
|
|
foo3(a : 2, b : 4)
|
|
}
|
|
|
|
func g() {}
|
|
func h(_ x: () -> () = g) { x() }
|
|
|
|
// Tuple types cannot have default values, but recover well here.
|
|
func tupleTypes() {
|
|
typealias ta1 = (a : Int = ()) // expected-error{{default argument not permitted in a tuple type}}{{28-32=}}
|
|
// expected-error @-1{{cannot create a single-element tuple with an element label}}{{20-24=}}
|
|
var c1 : (a : Int, b : Int, c : Int = 3, // expected-error{{default argument not permitted in a tuple type}}{{39-42=}}
|
|
d = 4) = (1, 2, 3, 4) // expected-error{{default argument not permitted in a tuple type}}{{15-18=}} expected-error{{use of undeclared type 'd'}}
|
|
}
|
|
|
|
func returnWithDefault() -> (a: Int, b: Int = 42) { // expected-error{{default argument not permitted in a tuple type}} {{45-49=}}
|
|
return 5 // expected-error{{cannot convert return expression of type 'Int' to return type '(a: Int, b: Int)'}}
|
|
}
|
|
|
|
func selectorStyle(_ i: Int = 1, withFloat f: Float = 2) { }
|
|
|
|
// Default arguments of constructors.
|
|
struct Ctor {
|
|
init (i : Int = 17, f : Float = 1.5) { }
|
|
}
|
|
|
|
Ctor() // expected-warning{{unused}}
|
|
Ctor(i: 12) // expected-warning{{unused}}
|
|
Ctor(f:12.5) // expected-warning{{unused}}
|
|
|
|
// Default arguments for nested constructors/functions.
|
|
struct Outer<T> {
|
|
struct Inner { // expected-error{{type 'Inner' cannot be nested in generic type 'Outer'}}
|
|
struct VeryInner {// expected-error{{type 'VeryInner' cannot be nested in generic type 'Inner'}}
|
|
init (i : Int = 17, f : Float = 1.5) { }
|
|
static func f(i: Int = 17, f: Float = 1.5) { }
|
|
func g(i: Int = 17, f: Float = 1.5) { }
|
|
}
|
|
}
|
|
}
|
|
Outer<Int>.Inner.VeryInner() // expected-warning{{unused}}
|
|
Outer<Int>.Inner.VeryInner(i: 12) // expected-warning{{unused}}
|
|
Outer<Int>.Inner.VeryInner(f:12.5) // expected-warning{{unused}}
|
|
Outer<Int>.Inner.VeryInner.f()
|
|
Outer<Int>.Inner.VeryInner.f(i: 12)
|
|
Outer<Int>.Inner.VeryInner.f(f:12.5)
|
|
|
|
var vi : Outer<Int>.Inner.VeryInner
|
|
vi.g()
|
|
vi.g(i: 12)
|
|
vi.g(f:12.5)
|
|
|
|
// <rdar://problem/14564964> crash on invalid
|
|
func foo(_ x: WonkaWibble = 17) { } // expected-error{{use of undeclared type 'WonkaWibble'}}
|
|
|
|
// Default arguments for initializers.
|
|
class SomeClass2 {
|
|
init(x: Int = 5) {}
|
|
}
|
|
class SomeDerivedClass2 : SomeClass2 {
|
|
init() {
|
|
super.init()
|
|
}
|
|
}
|
|
|
|
func shouldNotCrash(_ a : UndefinedType, bar b : Bool = true) { // expected-error {{use of undeclared type 'UndefinedType'}}
|
|
}
|
|
|
|
// <rdar://problem/20749423> Compiler crashed while building simple subclass
|
|
// code
|
|
class SomeClass3 {
|
|
init(x: Int = 5, y: Int = 5) {}
|
|
}
|
|
class SomeDerivedClass3 : SomeClass3 {}
|
|
_ = SomeDerivedClass3()
|
|
|
|
// Tuple types with default arguments are not materializable
|
|
func identity<T>(_ t: T) -> T { return t }
|
|
func defaultArgTuplesNotMaterializable(_ x: Int, y: Int = 0) {}
|
|
|
|
defaultArgTuplesNotMaterializable(identity(5))
|
|
|
|
// <rdar://problem/22333090> QoI: Propagate contextual information in a call to operands
|
|
defaultArgTuplesNotMaterializable(identity((5, y: 10)))
|
|
// expected-error@-1 {{cannot convert value of type '(Int, y: Int)' to expected argument type 'Int'}}
|
|
|
|
|
|
// rdar://problem/21799331
|
|
func foo<T>(_ x: T, y: Bool = true) {}
|
|
|
|
foo(true ? "foo" : "bar")
|
|
|
|
func foo2<T>(_ x: T, y: Bool = true) {}
|
|
|
|
extension Array {
|
|
func bar(_ x: (Element) -> Bool) -> Int? { return 0 }
|
|
}
|
|
|
|
foo2([].bar { $0 == "c" }!)
|
|
|
|
// rdar://problem/21643052
|
|
let a = ["1", "2"].map { Int($0) }
|
|
|
|
// Default arguments for static members used via ".foo"
|
|
struct X<T> {
|
|
static func foo(i: Int, j: Int = 0) -> X {
|
|
return X()
|
|
}
|
|
|
|
static var bar: X { return X() }
|
|
}
|
|
|
|
let testXa: X<Int> = .foo(i: 0)
|
|
let testXb: X<Int> = .bar
|