Skip to content

Commit 4655fc3

Browse files
committed
Sema: Make a couple of TypeResolver methods idempotent
When emitting a diagnostic, mark the TypeRepr as invalid and return an ErrorType to ensure that the diagnostic is not emitted again, and to muffle downstream diagnostics.
1 parent 0deacdc commit 4655fc3

File tree

12 files changed

+35
-31
lines changed

12 files changed

+35
-31
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,6 +2638,8 @@ TypeResolver::resolveAttributedType(TypeAttributes &attrs, TypeRepr *repr,
26382638
diagnoseInvalid(repr, loc, diag::escaping_non_function_parameter)
26392639
.fixItRemove(attrRange);
26402640
}
2641+
2642+
ty = ErrorType::get(getASTContext());
26412643
}
26422644

26432645
attrs.clearAttribute(TAK_escaping);
@@ -3853,6 +3855,8 @@ TypeResolver::resolveCompositionType(CompositionTypeRepr *repr,
38533855
return false;
38543856
};
38553857

3858+
bool IsInvalid = false;
3859+
38563860
for (auto tyR : repr->getTypes()) {
38573861
auto ty = resolveType(tyR,
38583862
options.withContext(TypeResolverContext::GenericRequirement));
@@ -3885,6 +3889,13 @@ TypeResolver::resolveCompositionType(CompositionTypeRepr *repr,
38853889
diagnose(tyR->getStartLoc(),
38863890
diag::invalid_protocol_composition_member,
38873891
ty);
3892+
3893+
IsInvalid = true;
3894+
}
3895+
3896+
if (IsInvalid) {
3897+
repr->setInvalid();
3898+
return ErrorType::get(getASTContext());
38883899
}
38893900

38903901
// Avoid confusing diagnostics ('MyClass' not convertible to 'MyClass',

test/Compatibility/protocol_composition.swift

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,16 @@ typealias A1 = P1.Type & P2 // expected-error {{non-protocol, non-class type 'P1
3434
// BEGIN swift4.swift
3535

3636
func foo(x: P1 & Any & P2.Type?) { // expected-error {{non-protocol, non-class type 'P2.Type?' cannot be used within a protocol-constrained type}}
37-
let _: (P1 & P2).Type? = x // expected-error {{cannot convert value of type 'P1' to specified type '(P1 & P2).Type?'}}
38-
let _: (P1 & P2).Type = x! // expected-error {{cannot force unwrap value of non-optional type 'P1'}}
39-
// expected-error@-1 {{cannot convert value of type 'P1' to specified type '(P1 & P2).Type'}}
40-
let _: Int = x!.p1() // expected-error {{cannot force unwrap value of non-optional type 'P1'}} expected-error {{static member 'p1' cannot be used on instance of type 'P1'}}
41-
let _: Int? = x?.p2 // expected-error {{cannot use optional chaining on non-optional value of type 'P1'}}
42-
// expected-error@-1 {{value of type 'P1' has no member 'p2'}}
37+
let _: (P1 & P2).Type? = x
38+
let _: (P1 & P2).Type = x!
39+
40+
let _: Int = x!.p1()
41+
let _: Int? = x?.p2
4342
}
4443

4544
func bar() -> ((P1 & P2)?).Type {
4645
let x = (P1 & P2?).self // expected-error {{non-protocol, non-class type 'P2?' cannot be used within a protocol-constrained type}}
47-
return x // expected-error {{cannot convert return expression}}
46+
return x
4847
}
4948

5049
typealias A1 = P1.Type & P2 // expected-error {{non-protocol, non-class type 'P1.Type' cannot be used within a protocol-constrained type}}

test/Constraints/same_types.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,9 @@ func testSameTypeCommutativity4<U, T>(_ t: T, _ u: U)
304304
func testSameTypeCommutativity5<U, T: P1>(_ t: T, _ u: U)
305305
where PPP & P3 == T.Assoc { } // Ok, equivalent to T.Assoc == PPP & P3
306306

307-
// FIXME: Error emitted twice.
308307
func testSameTypeCommutativity6<U, T: P1>(_ t: T, _ u: U)
309308
where U & P3 == T.Assoc { } // Equivalent to T.Assoc == U & P3
310-
// expected-error@-1 2 {{non-protocol, non-class type 'U' cannot be used within a protocol-constrained type}}
309+
// expected-error@-1 {{non-protocol, non-class type 'U' cannot be used within a protocol-constrained type}}
311310

312311
// rdar;//problem/46848889
313312
struct Foo<A: P1, B: P1, C: P1> where A.Assoc == B.Assoc, A.Assoc == C.Assoc {}

test/Generics/function_defs.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
22

33
//===----------------------------------------------------------------------===//
44
// Type-check function definitions
@@ -288,13 +288,10 @@ func badTypeConformance3<T>(_: T) where (T) -> () : EqualComparable { }
288288
// expected-error@-1{{type '(T) -> ()' in conformance requirement does not refer to a generic parameter or associated type}}
289289

290290
func badTypeConformance4<T>(_: T) where @escaping (inout T) throws -> () : EqualComparable { }
291-
// expected-error@-1{{type '(inout T) throws -> ()' in conformance requirement does not refer to a generic parameter or associated type}}
292-
// expected-error@-2 2 {{@escaping attribute may only be used in function parameter position}}
291+
// expected-error@-1 {{@escaping attribute may only be used in function parameter position}}
293292

294-
// FIXME: Error emitted twice.
295293
func badTypeConformance5<T>(_: T) where T & Sequence : EqualComparable { }
296-
// expected-error@-1 2 {{non-protocol, non-class type 'T' cannot be used within a protocol-constrained type}}
297-
// expected-error@-2{{type 'Sequence' in conformance requirement does not refer to a generic parameter or associated type}}
294+
// expected-error@-1 {{non-protocol, non-class type 'T' cannot be used within a protocol-constrained type}}
298295

299296
func badTypeConformance6<T>(_: T) where [T] : Collection { }
300297
// expected-error@-1{{type '[T]' in conformance requirement does not refer to a generic parameter or associated type}}

test/Generics/generic_types.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
22

33
protocol MyFormattedPrintable {
44
func myFormat() -> String
@@ -230,7 +230,7 @@ class Top {}
230230
class Bottom<T : Bottom<Top>> {}
231231
// expected-error@-1 {{'Bottom' requires that 'Top' inherit from 'Bottom<Top>'}}
232232
// expected-note@-2 {{requirement specified as 'T' : 'Bottom<Top>' [with T = Top]}}
233-
// expected-error@-3 3{{generic class 'Bottom' has self-referential generic requirements}}
233+
// expected-error@-3 *{{generic class 'Bottom' has self-referential generic requirements}}
234234

235235
// Invalid inheritance clause
236236

test/IDE/complete_override.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ class Deprecated2 : Deprecated1 {
442442
// DEPRECATED_1: Decl[InstanceMethod]/Super/NotRecommended: deprecated() {|};
443443

444444
class EscapingBase {
445-
func method(_ x: @escaping (@escaping ()->()) -> (()->())) -> (@escaping (@escaping ()->() )->()) { }
445+
func method(_ x: @escaping (@escaping ()->()) -> (()->())) -> ((@escaping ()->() )->()) { }
446446
func autoclosure(arg: @autoclosure () -> Bool) {}
447447
}
448448
class Escaping : EscapingBase {

test/decl/protocol/req/associated_type_ambiguity.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-inferred-signatures=on -requirement-machine-protocol-signatures=on
22
// RUN: not %target-swift-frontend -typecheck %s -debug-generic-signatures -requirement-machine-inferred-signatures=on -requirement-machine-protocol-signatures=on 2>&1 | %FileCheck %s
33

44
protocol P1 {
5-
typealias T = Int // expected-note 3{{found this candidate}}
5+
typealias T = Int // expected-note {{found this candidate}}
66
}
77

88
protocol P2 {
9-
associatedtype T // expected-note 3{{found this candidate}}
9+
associatedtype T // expected-note {{found this candidate}}
1010
}
1111

1212
// CHECK: ExtensionDecl line={{.*}} base=P1
1313
// CHECK-NEXT: Generic signature: <Self where Self : P1, Self : P2>
1414
extension P1 where Self : P2, T == Int { // expected-error {{'T' is ambiguous for type lookup in this context}}
15-
func takeT11(_: T) {} // expected-error {{'T' is ambiguous for type lookup in this context}}
15+
func takeT11(_: T) {}
1616
func takeT12(_: Self.T) {}
1717
}
1818

@@ -24,7 +24,7 @@ extension P1 where Self : P2, Self.T == Int {
2424
}
2525

2626
extension P1 where Self : P2 {
27-
func takeT31(_: T) {} // expected-error {{'T' is ambiguous for type lookup in this context}}
27+
func takeT31(_: T) {}
2828
func takeT32(_: Self.T) {}
2929
}
3030

test/decl/typealias/generic.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %target-typecheck-verify-swift
1+
// RUN: %target-typecheck-verify-swift -requirement-machine-protocol-signatures=verify -requirement-machine-inferred-signatures=verify
22

33
struct MyType<TyA, TyB> { // expected-note {{generic type 'MyType' declared here}}
44
// expected-note @-1 {{arguments to generic parameter 'TyB' ('S' and 'Int') are expected to be equal}}

test/expr/expressions.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ func test_lambda2() {
263263
{ () -> protocol<Int> in
264264
// expected-error @-1 {{'protocol<...>' composition syntax has been removed and is not needed here}} {{11-24=Int}}
265265
// expected-error @-2 {{non-protocol, non-class type 'Int' cannot be used within a protocol-constrained type}}
266-
// expected-warning @-3 {{result of call to closure returning 'Any' is unused}}
266+
// expected-warning @-3 {{result of call to closure returning 'Int' is unused}}
267267
return 1
268268
}()
269269
}

test/type/parameterized_protocol.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,4 @@ protocol SomeProto {}
148148

149149
func protocolCompositionNotSupported(_: SomeProto & Sequence<Int>) {}
150150
// expected-error@-1 {{non-protocol, non-class type 'Sequence<Int>' cannot be used within a protocol-constrained type}}
151-
// expected-warning@-2 {{protocol 'Sequence' as a type must be explicitly marked as 'any'}}
152151

153-
// FIXME: The second diagnostic is bogus.

0 commit comments

Comments
 (0)