Skip to content

Commit 704244b

Browse files
committed
ExistentialTypeSyntaxChecker: Fix any fix-it for inverse constraints
1 parent 89f6d27 commit 704244b

File tree

3 files changed

+79
-103
lines changed

3 files changed

+79
-103
lines changed

lib/Sema/TypeCheckType.cpp

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -6085,14 +6085,19 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
60856085
auto replacementIt = it;
60866086

60876087
// Backtrack the stack and expand the replacement range to any parent
6088-
// compositions or `.Type` metatypes, skipping only parentheses.
6088+
// inverses, compositions or `.Type` metatypes, skipping only parentheses.
6089+
//
6090+
// E.g. `(X & ~P).Type` → `any (X & ~P).Type`.
6091+
//
6092+
// We're here
60896093
do {
60906094
--it;
60916095
if ((*it)->isParenType()) {
60926096
continue;
60936097
}
60946098

6095-
if (isa<CompositionTypeRepr>(*it) || isa<MetatypeTypeRepr>(*it)) {
6099+
if (isa<InverseTypeRepr>(*it) || isa<CompositionTypeRepr>(*it) ||
6100+
isa<MetatypeTypeRepr>(*it)) {
60966101
replacementIt = it;
60976102
continue;
60986103
}
@@ -6176,23 +6181,12 @@ class ExistentialTypeSyntaxChecker : public ASTWalker {
61766181
continue;
61776182
}
61786183

6179-
if (auto inverse = dyn_cast<InverseTypeRepr>(*it)) {
6180-
if (isAnyOrSomeMissing()) {
6181-
// Find an enclosing protocol composition, if there is one, so we
6182-
// can insert 'any' before that.
6183-
SourceLoc anyLoc = inverse->getTildeLoc();
6184-
if (it != reprStack.begin()) {
6185-
if (auto *comp = dyn_cast<CompositionTypeRepr>(*(it - 1))) {
6186-
anyLoc = comp->getStartLoc();
6187-
}
6188-
}
6189-
6190-
Ctx.Diags.diagnose(inverse->getTildeLoc(), diag::inverse_requires_any)
6191-
.highlight(inverse->getConstraint()->getSourceRange())
6192-
.fixItInsert(anyLoc, "any ");
6193-
6194-
return;
6195-
}
6184+
if (auto *inverse = dyn_cast<InverseTypeRepr>(*it);
6185+
inverse && isAnyOrSomeMissing()) {
6186+
auto diag = Ctx.Diags.diagnose(inverse->getTildeLoc(),
6187+
diag::inverse_requires_any);
6188+
emitInsertAnyFixit(diag, T);
6189+
return;
61966190
}
61976191
}
61986192

test/type/explicit_existential.swift

Lines changed: 33 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -305,48 +305,48 @@ func testAnyFixIt() {
305305

306306
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=any HasAssoc}}
307307
let _: HasAssoc
308-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
308+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-19=any ~Copyable}}
309309
let _: ~Copyable
310310
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}}
311311
let _: (HasAssoc)
312-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
312+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-21=any ~(Copyable)}}
313313
let _: ~(Copyable)
314314
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{19-27=any HasAssoc}}
315315
let _: Optional<HasAssoc>
316-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-19=any }}
316+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{19-28=any ~Copyable}}
317317
let _: Optional<~Copyable>
318318
// FIXME: No fix-it + generic argument not diagnosed.
319319
// expected-error@+1 {{use of protocol 'HasAssocGeneric<any HasAssoc>' as a type must be written 'any HasAssocGeneric<any HasAssoc>'}}{{none}}
320320
let _: HasAssocGeneric<HasAssoc>
321321
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{14-22=any HasAssoc}}
322322
let _: S.G<HasAssoc>
323-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-26=any }}
323+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{26-35=any ~Copyable}}
324324
let _: S.NonCopyable_G<~Copyable>
325325
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}}
326326
let _: G<HasAssoc>.S
327-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }}
327+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}}
328328
let _: NonCopyable_G<~Copyable>.S
329329
// expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}}
330330
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}}
331331
let _: G<HasAssoc>.G<HasAssoc>
332-
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }}
333-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }}
332+
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}}
333+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-58=any ~Copyable}}
334334
let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable>
335335
// expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}}
336336
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{24-32=any HasAssoc}}
337337
let _: G<HasAssoc>.G<HasAssoc>.S
338-
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-24=any }}
339-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-49=any }}
338+
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{24-33=any ~Copyable}}
339+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{49-58=any ~Copyable}}
340340
let _: NonCopyable_G<~Copyable>.NonCopyable_G<~Copyable>.S
341341
// expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-26=any S.HasAssoc_Alias}}
342342
let _: S.HasAssoc_Alias
343-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
343+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-27=any ~S.Copyable_Alias}}
344344
let _: ~S.Copyable_Alias
345345
// expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{12-20=any HasAssoc}}
346346
// expected-error@+1 {{use of 'S.HasAssoc_Alias' (aka 'HasAssoc') as a type must be written 'any S.HasAssoc_Alias' (aka 'any HasAssoc')}}{{10-36=any G<HasAssoc>.HasAssoc_Alias}}
347347
let _: G<HasAssoc>.HasAssoc_Alias
348348
// expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{13-21=any HasAssoc}}
349-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
349+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-37=any ~G<HasAssoc>.Copyable_Alias}}
350350
let _: ~G<HasAssoc>.Copyable_Alias
351351
// FIXME: No fix-it + generic argument not diagnosed.
352352
// expected-error@+1 {{use of 'HasAssocGeneric<any HasAssoc>' as a type must be written 'any HasAssocGeneric<any HasAssoc>}}{{none}}
@@ -356,31 +356,27 @@ func testAnyFixIt() {
356356
let _: HasAssoc.HasAssoc_Alias.Int_Alias
357357
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=any HasAssoc.Type}}
358358
let _: HasAssoc.Type
359-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
359+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-24=any ~Copyable.Type}}
360360
let _: ~Copyable.Type
361361
// expected-error@+1 {{type 'any Copyable.Type' cannot be suppressed}}
362362
let _: ~(Copyable.Type)
363363
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-25=any (HasAssoc).Type}}
364364
let _: (HasAssoc).Type
365-
// FIXME: Fix-it produces singleton, not existential, metatype type?
366-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
365+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=any (~Copyable).Type}}
367366
let _: (~Copyable).Type
368367
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-27=any ((HasAssoc)).Type}}
369368
let _: ((HasAssoc)).Type
370-
// FIXME: Fix-it produces singleton, not existential, metatype type?
371-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{12-12=any }}
369+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-28=any ((~Copyable)).Type}}
372370
let _: ((~Copyable)).Type
373371
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=any HasAssoc.Type.Type}}
374372
let _: HasAssoc.Type.Type
375373
// expected-error@+1 {{type 'any Copyable.Type.Type' cannot be suppressed}}
376374
let _: ~Copyable.Type.Type
377-
// FIXME: Fix-it produces singleton, not existential, metatype type?
378-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
375+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=any (~Copyable).Type.Type}}
379376
let _: (~Copyable).Type.Type
380377
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-30=any (HasAssoc.Type).Type}}
381378
let _: (HasAssoc.Type).Type
382-
// FIXME: Fix-it produces singleton, not existential, metatype type?
383-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
379+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=any (~Copyable.Type).Type}}
384380
let _: (~Copyable.Type).Type
385381
// expected-error@+2 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}}
386382
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=(any HasAssoc)}}
@@ -390,12 +386,12 @@ func testAnyFixIt() {
390386
let _: (HasAssoc).Protocol = (HasAssoc).self
391387
// expected-error@+1 {{type '(any Copyable).Type' cannot be suppressed}}
392388
let _: ~Copyable.Protocol
393-
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
394-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-34=any }}
389+
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}}
390+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{34-43=any ~Copyable}}
395391
let _: (~Copyable).Protocol = (~Copyable).self
396392
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}}
397393
let _: HasAssoc.Protocol.Type.Type
398-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
394+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}}
399395
let _: (~Copyable).Protocol.Type.Type
400396
do {
401397
let meta: S.Type
@@ -409,39 +405,36 @@ func testAnyFixIt() {
409405
let _: HasAssoc.Type.Protocol
410406
// expected-error@+1 {{type '(any Copyable.Type).Type' cannot be suppressed}}
411407
let _: ~Copyable.Type.Protocol
412-
// FIXME: Incorrect fix-it.
413-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
408+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}}
414409
let _: (~Copyable).Type.Protocol
415410
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-28=(any HasAssoc.Type.Type)}}
416411
let _: HasAssoc.Type.Type.Protocol
417-
// FIXME: Incorrect fix-it.
418-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
412+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-31=(any (~Copyable).Type.Type)}}
419413
let _: (~Copyable).Type.Type.Protocol
420414
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}}
421415
let _: HasAssoc?
422416
// expected-error@+1 {{type '(any Copyable)?' cannot be suppressed}}
423417
let _: ~Copyable?
424418
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{11-19=any HasAssoc}}
425419
let _: (HasAssoc)?
426-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
420+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}}
427421
let _: (~Copyable)?
428422
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-23=(any HasAssoc.Type)}}
429423
let _: HasAssoc.Type?
430-
// FIXME: Fix-it produces singleton, not existential, metatype type?
431-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
424+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{10-26=(any (~Copyable).Type)}}
432425
let _: (~Copyable).Type?
433426
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-18=(any HasAssoc)}}
434427
let _: HasAssoc.Protocol?
435-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-11=any }}
428+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{11-20=any ~Copyable}}
436429
let _: (~Copyable).Protocol?
437430
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{21-29=any HasAssoc}}
438431
let _: (borrowing HasAssoc) -> Void
439-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }}
432+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{21-30=any ~Copyable}}
440433
let _: (borrowing ~Copyable) -> Void
441434
// https://github.com/apple/swift/issues/72588
442435
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{30-38=any HasAssoc}}
443436
let _: any HasAssocGeneric<HasAssoc>
444-
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-30=any }}
437+
// expected-error@+1 {{constraint that suppresses conformance requires 'any'}}{{30-39=any ~Copyable}}
445438
let _: any HasAssocGeneric<~Copyable>
446439
// expected-error@+1 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{16-24=any HasAssoc}}
447440
let _: any G<HasAssoc>.HasAssoc_Alias
@@ -455,26 +448,24 @@ func testAnyFixIt() {
455448
// expected-error@+2:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}}
456449
// expected-error@+1:21 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-29=any HasAssoc & HasAssoc}}
457450
let _: HasAssoc & HasAssoc
458-
// expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
459-
// expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
451+
// expected-error@+2:10 {{constraint that suppresses conformance requires 'any'}}{{10-31=any ~Copyable & ~Copyable}}
452+
// expected-error@+1:22 {{constraint that suppresses conformance requires 'any'}}{{10-31=any ~Copyable & ~Copyable}}
460453
let _: ~Copyable & ~Copyable
461454
// expected-error@+3:10 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}}
462455
// expected-error@+2:22 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}}
463456
// expected-error@+1:33 {{use of protocol 'HasAssoc' as a type must be written 'any HasAssoc'}}{{10-42=any HasAssoc & (HasAssoc & HasAssoc)}}
464457
let _: HasAssoc & (HasAssoc & HasAssoc)
465-
// FIXME: Incorrect fix-its for nested composition.
466-
// expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-10=any }}
467-
// expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }}
468-
// expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{23-23=any }}
458+
// expected-error@+3:10 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}}
459+
// expected-error@+2:23 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}}
460+
// expected-error@+1:35 {{constraint that suppresses conformance requires 'any'}}{{10-45=any ~Copyable & (~Copyable & ~Copyable)}}
469461
let _: ~Copyable & (~Copyable & ~Copyable)
470462

471463
// Misc. compound cases.
472464

473-
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-21=any }}
465+
// expected-error@+2 {{constraint that suppresses conformance requires 'any'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}}
474466
// expected-error@+1 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{21-52=any NonCopyableHasAssoc & ~Copyable}}
475467
let _: (borrowing NonCopyableHasAssoc & ~Copyable) -> Void
476-
// FIXME: Incorrect fix-it.
477-
// expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{15-15=any }}
468+
// expected-error@+3:15 {{constraint that suppresses conformance requires 'any'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}}
478469
// expected-error@+2:28 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}}
479470
// expected-error@+1:51 {{use of protocol 'NonCopyableHasAssoc' as a type must be written 'any NonCopyableHasAssoc'}}{{10-88=(any (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type)}}
480471
let _: (((((~Copyable) & NonCopyableHasAssoc) & NonCopyableHasAssoc).Type.Type)).Type?

0 commit comments

Comments
 (0)