Skip to content

Commit 1df3d1a

Browse files
committed
Frontend: Don't interleave parsing and typechecking for the main file
SIL files still require this behavior; if we cleaned that up we could simplify a fair bit of code here. Fixes <https://bugs.swift.org/browse/SR-284>, <https://bugs.swift.org/browse/SR-4426>.
1 parent 8b11223 commit 1df3d1a

20 files changed

+115
-94
lines changed

lib/Frontend/Frontend.cpp

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -851,8 +851,8 @@ void CompilerInstance::parseAndCheckTypesUpTo(
851851

852852
// Type-check main file after parsing all other files so that
853853
// it can use declarations from other files.
854-
// In addition, the main file has parsing and type-checking
855-
// interwined.
854+
// In addition, in SIL mode the main file has parsing and
855+
// type-checking interwined.
856856
if (MainBufferID != NO_SUCH_BUFFER) {
857857
parseAndTypeCheckMainFileUpTo(limitStage);
858858
}
@@ -977,24 +977,35 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
977977
parseIntoSourceFile(MainFile, MainFile.getBufferID().getValue(), &Done,
978978
TheSILModule ? &SILContext : nullptr,
979979
PersistentState.get(),
980-
/*DelayedBodyParsing=*/false);
980+
!mainIsPrimary);
981981

982-
if (mainIsPrimary && (Done || CurTUElem < MainFile.Decls.size())) {
982+
// For SIL we actually have to interleave parsing and type checking
983+
// because the SIL parser expects to see fully type checked declarations.
984+
if (TheSILModule) {
985+
if (Done || CurTUElem < MainFile.Decls.size()) {
986+
assert(mainIsPrimary);
987+
performTypeChecking(MainFile, CurTUElem);
988+
}
989+
}
990+
991+
CurTUElem = MainFile.Decls.size();
992+
} while (!Done);
993+
994+
if (!TheSILModule) {
995+
if (mainIsPrimary) {
983996
switch (LimitStage) {
984997
case SourceFile::Parsing:
985998
case SourceFile::Parsed:
986999
llvm_unreachable("invalid limit stage");
9871000
case SourceFile::NameBound:
988-
performNameBinding(MainFile, CurTUElem);
1001+
performNameBinding(MainFile);
9891002
break;
9901003
case SourceFile::TypeChecked:
991-
performTypeChecking(MainFile, CurTUElem);
1004+
performTypeChecking(MainFile);
9921005
break;
9931006
}
9941007
}
995-
996-
CurTUElem = MainFile.Decls.size();
997-
} while (!Done);
1008+
}
9981009

9991010
Diags.setSuppressWarnings(DidSuppressWarnings);
10001011

@@ -1003,8 +1014,10 @@ void CompilerInstance::parseAndTypeCheckMainFileUpTo(
10031014
performDebuggerTestingTransform(MainFile);
10041015
}
10051016

1006-
if (!mainIsPrimary) {
1007-
performNameBinding(MainFile);
1017+
if (!TheSILModule) {
1018+
if (!mainIsPrimary) {
1019+
performNameBinding(MainFile);
1020+
}
10081021
}
10091022
}
10101023

test/Constraints/closures.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ overloaded { print("hi"); print("bye") } // multiple expression closure without
763763
// expected-error@-1 {{ambiguous use of 'overloaded'}}
764764

765765
func not_overloaded(_ handler: () -> Int) {}
766+
// expected-note@-1 {{'not_overloaded' declared here}}
766767

767768
not_overloaded { } // empty body
768769
// expected-error@-1 {{cannot convert value of type '()' to closure result type 'Int'}}

test/Constraints/diagnostics.swift

Lines changed: 14 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ f3(
7272
f4(i, d) // expected-error {{extra argument in call}}
7373

7474
// Missing member.
75-
i.wobble() // expected-error{{value of type 'Int' has no member 'wobble'}}
75+
i.missingMember() // expected-error{{value of type 'Int' has no member 'missingMember'}}
7676

7777
// Generic member does not conform.
7878
extension Int {
@@ -100,11 +100,11 @@ func f7() -> (c: Int, v: A) {
100100
}
101101

102102
func f8<T:P2>(_ n: T, _ f: @escaping (T) -> T) {} // expected-note {{where 'T' = 'Int'}}
103-
// expected-note@-1 {{required by global function 'f8' where 'T' = 'Tup' (aka '(Int, Double)')}}
103+
// expected-note@-1 {{required by global function 'f8' where 'T' = '(Int, Double)'}}
104104
f8(3, f4) // expected-error {{global function 'f8' requires that 'Int' conform to 'P2'}}
105105
typealias Tup = (Int, Double)
106106
func f9(_ x: Tup) -> Tup { return x }
107-
f8((1,2.0), f9) // expected-error {{type 'Tup' (aka '(Int, Double)') cannot conform to 'P2'; only struct/enum/class types can conform to protocols}}
107+
f8((1,2.0), f9) // expected-error {{type '(Int, Double)' cannot conform to 'P2'; only struct/enum/class types can conform to protocols}}
108108

109109
// <rdar://problem/19658691> QoI: Incorrect diagnostic for calling nonexistent members on literals
110110
1.doesntExist(0) // expected-error {{value of type 'Int' has no member 'doesntExist'}}
@@ -1144,24 +1144,6 @@ for var i in 0..<10 { // expected-warning {{variable 'i' was never mutated; cons
11441144
_ = i + 1
11451145
}
11461146

1147-
// rdar://problem/32726044 - shrink reduced domains too far
1148-
1149-
public protocol P_32726044 {}
1150-
1151-
extension Int: P_32726044 {}
1152-
extension Float: P_32726044 {}
1153-
1154-
public func *(lhs: P_32726044, rhs: P_32726044) -> Double {
1155-
fatalError()
1156-
}
1157-
1158-
func rdar32726044() -> Float {
1159-
var f: Float = 0
1160-
f = Float(1) * 100 // Ok
1161-
let _: Float = Float(42) + 0 // Ok
1162-
return f
1163-
}
1164-
11651147
// SR-5045 - Attempting to return result of reduce(_:_:) in a method with no return produces ambiguous error
11661148
func sr5045() {
11671149
let doubles: [Double] = [1, 2, 3]
@@ -1294,16 +1276,18 @@ func unresolvedTypeExistential() -> Bool {
12941276
func rdar43525641(_ a: Int, _ b: Int = 0, c: Int = 0, _ d: Int) {}
12951277
rdar43525641(1, c: 2, 3) // Ok
12961278

1297-
struct Array {}
1298-
let foo: Swift.Array = Array() // expected-error {{cannot convert value of type 'Array' to specified type 'Array<Element>'}}
1299-
// expected-error@-1 {{generic parameter 'Element' could not be inferred}}
1279+
do {
1280+
struct Array {}
1281+
let foo: Swift.Array = Array() // expected-error {{cannot convert value of type 'Array' to specified type 'Array<Element>'}}
1282+
// expected-error@-1 {{generic parameter 'Element' could not be inferred}}
13001283

1301-
struct Error {}
1302-
let bar: Swift.Error = Error() //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1303-
let baz: (Swift.Error) = Error() //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1304-
let baz2: Swift.Error = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1305-
let baz3: (Swift.Error) = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1306-
let baz4: ((Swift.Error)) = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1284+
struct Error {}
1285+
let bar: Swift.Error = Error() //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1286+
let baz: (Swift.Error) = Error() //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1287+
let baz2: Swift.Error = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1288+
let baz3: (Swift.Error) = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1289+
let baz4: ((Swift.Error)) = (Error()) //expected-error {{value of type 'diagnostics.Error' does not conform to specified type 'Swift.Error'}}
1290+
}
13071291

13081292
// SyntaxSugarTypes with unresolved types
13091293
func takesGenericArray<T>(_ x: [T]) {}

test/Constraints/dynamic_lookup.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ func rdar29960565(_ o: AnyObject) {
267267

268268
@objc class DynamicIUO : NSObject, Q {
269269
@objc var t: String! = ""
270-
@objc func bar() -> String! {}
270+
@objc func baz() -> String! {}
271271
@objc subscript(_: DynamicIUO) -> DynamicIUO! {
272272
get {
273273
return self
@@ -299,11 +299,11 @@ let _: String = o.t
299299
let _: String = o.t!
300300
let _: String = o.t!!
301301
let _: String? = o.t
302-
let _: String = o.bar()
303-
let _: String = o.bar!()
304-
let _: String = o.bar()!
305-
let _: String = o.bar!()!
306-
let _: String? = o.bar()
302+
let _: String = o.baz()
303+
let _: String = o.baz!()
304+
let _: String = o.baz()!
305+
let _: String = o.baz!()!
306+
let _: String? = o.baz()
307307
let _: DynamicIUO = o[dyn_iuo]
308308
let _: DynamicIUO = o[dyn_iuo]!
309309
let _: DynamicIUO = o[dyn_iuo]!!

test/Constraints/members.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -567,15 +567,15 @@ func rdar_48114578() {
567567
}
568568

569569
struct S_Min {
570-
var min: Int = 42
570+
var xmin: Int = 42
571571
}
572572

573-
func min(_: Int, _: Float) -> Int { return 0 }
574-
func min(_: Float, _: Int) -> Int { return 0 }
573+
func xmin(_: Int, _: Float) -> Int { return 0 }
574+
func xmin(_: Float, _: Int) -> Int { return 0 }
575575

576576
extension S_Min : CustomStringConvertible {
577577
public var description: String {
578-
return "\(min)" // Ok
578+
return "\(xmin)" // Ok
579579
}
580580
}
581581

test/Constraints/patterns.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ default:
8787
}
8888

8989
// Raise an error if pattern productions are used in expressions.
90-
var b = var a // expected-error{{expected initial value after '='}} expected-error {{type annotation missing in pattern}} expected-error {{consecutive statements on a line must be separated by ';'}} {{8-8=;}}
90+
var b = var x // expected-error{{expected initial value after '='}} expected-error {{type annotation missing in pattern}} expected-error {{consecutive statements on a line must be separated by ';'}} {{8-8=;}}
9191
var c = is Int // expected-error{{expected initial value after '='}} expected-error {{expected expression}} expected-error {{consecutive statements on a line must be separated by ';'}} {{8-8=;}}
9292

9393
// TODO: Bad recovery in these cases. Although patterns are never valid

test/Constraints/rdar32726044.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// rdar://problem/32726044 - shrink reduced domains too far
4+
public protocol P_32726044 {}
5+
6+
extension Int: P_32726044 {}
7+
extension Float: P_32726044 {}
8+
9+
public func *(lhs: P_32726044, rhs: P_32726044) -> Double {
10+
fatalError()
11+
}
12+
13+
func rdar32726044() -> Float {
14+
var f: Float = 0
15+
f = Float(1) * 100 // Ok
16+
let _: Float = Float(42) + 0 // Ok
17+
return f
18+
}

test/Constraints/tuple_arguments.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,6 +1695,7 @@ class Mappable<T> {
16951695
}
16961696

16971697
let x = Mappable(())
1698+
// expected-note@-1 2{{'x' declared here}}
16981699
_ = x.map { (_: Void) in return () }
16991700
_ = x.map { (_: ()) in () }
17001701

test/Frontend/debug-diagnostic-names.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ let x =
55
// CHECK_NAMES: error: expected initial value after '=' [expected_init_value]{{$}}
66
// CHECK_NONAMES: error: expected initial value after '='{{$}}
77

8+
// CHECK_NAMES: warning: expression following 'return' is treated as an argument of the 'return' [unindented_code_after_return]{{$}}
9+
// CHECK_NAMES: note: indent the expression to silence this warning [indent_expression_to_silence]{{$}}
10+
// CHECK_NONAMES: warning: expression following 'return' is treated as an argument of the 'return'{{$}}
11+
// CHECK_NONAMES: note: indent the expression to silence this warning{{$}}
12+
func foo() -> Int {
13+
return
14+
42
15+
}
16+
817
guard let y = 0 else {}
918
// CHECK_NAMES: error: initializer for conditional binding must have Optional type, not 'Int' [condition_optional_element_pattern_not_valid_type]{{$}}
1019
// CHECK_NONAMES: error: initializer for conditional binding must have Optional type, not 'Int'{{$}}
1120

1221
let z: Double = ""
1322
// CHECK_NAMES: error: cannot convert value of type 'String' to specified type 'Double' [cannot_convert_initializer_value]{{$}}
1423
// CHECK_NONAMES: error: cannot convert value of type 'String' to specified type 'Double'{{$}}
15-
16-
func foo() -> Int {
17-
return
18-
42
19-
}
20-
// CHECK_NAMES: warning: expression following 'return' is treated as an argument of the 'return' [unindented_code_after_return]{{$}}
21-
// CHECK_NAMES: note: indent the expression to silence this warning [indent_expression_to_silence]{{$}}
22-
// CHECK_NONAMES: warning: expression following 'return' is treated as an argument of the 'return'{{$}}
23-
// CHECK_NONAMES: note: indent the expression to silence this warning{{$}}

test/NameBinding/accessibility.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ _ = PrivateInit() // expected-error {{'PrivateInit' initializer is inaccessible
6464
// TESTABLE: :[[@LINE-1]]:{{[^:]+}}: error: 'PrivateInit' initializer is inaccessible due to 'private' protection level
6565

6666
var s = StructWithPrivateSetter()
67+
// expected-note@-1 3{{did you mean 's'?}}
6768
s.x = 42 // expected-error {{cannot assign to property: 'x' setter is inaccessible}}
6869

6970
class Sub : Base {

0 commit comments

Comments
 (0)