Skip to content

Commit f42cd3b

Browse files
authored
Merge pull request #68288 from xedin/issue-67815-5.9
[5.9][PreCheck] Filter out macro declarations from result set
2 parents 94f8edd + 179fd96 commit f42cd3b

File tree

4 files changed

+86
-49
lines changed

4 files changed

+86
-49
lines changed

lib/Sema/CSGen.cpp

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1601,40 +1601,22 @@ namespace {
16011601
TVO_CanBindToLValue | TVO_CanBindToNoEscape);
16021602
ArrayRef<ValueDecl*> decls = expr->getDecls();
16031603
SmallVector<OverloadChoice, 4> choices;
1604-
bool anyMacros = false;
1605-
auto addChoices = [&](bool skipMacros) {
1606-
for (unsigned i = 0, n = decls.size(); i != n; ++i) {
1607-
// If the result is invalid, skip it.
1608-
// FIXME: Note this as invalid, in case we don't find a solution,
1609-
// so we don't let errors cascade further.
1610-
if (decls[i]->isInvalid())
1611-
continue;
1612-
1613-
// If the result is a macro, skip it if we're supposed to.
1614-
if (skipMacros && isa<MacroDecl>(decls[i])) {
1615-
anyMacros = true;
1616-
continue;
1617-
}
16181604

1619-
OverloadChoice choice =
1620-
OverloadChoice(Type(), decls[i], expr->getFunctionRefKind());
1621-
choices.push_back(choice);
1622-
}
1623-
};
1605+
for (unsigned i = 0, n = decls.size(); i != n; ++i) {
1606+
// If the result is invalid, skip it.
1607+
// FIXME: Note this as invalid, in case we don't find a solution,
1608+
// so we don't let errors cascade further.
1609+
if (decls[i]->isInvalid())
1610+
continue;
16241611

1625-
addChoices(/*skipMacros=*/true);
1612+
OverloadChoice choice =
1613+
OverloadChoice(Type(), decls[i], expr->getFunctionRefKind());
1614+
choices.push_back(choice);
1615+
}
16261616

16271617
if (choices.empty()) {
1628-
// If there are no valid overloads, but we ignored some macros, add
1629-
// the macros. This improves recovery when the user forgot the leading
1630-
// '#'.
1631-
if (anyMacros) {
1632-
addChoices(/*skipMacros=*/false);
1633-
assert(!choices.empty());
1634-
} else {
1635-
// There are no suitable overloads. Just fail.
1636-
return nullptr;
1637-
}
1618+
// There are no suitable overloads. Just fail.
1619+
return nullptr;
16381620
}
16391621

16401622
// Record this overload set.

lib/Sema/PreCheckExpr.cpp

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -650,16 +650,12 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
650650

651651
// FIXME: Need to refactor the way we build an AST node from a lookup result!
652652

653-
// If we have an unambiguous reference to a type decl, form a TypeExpr.
654-
if (Lookup.size() == 1 && UDRE->getRefKind() == DeclRefKind::Ordinary &&
655-
isa<TypeDecl>(Lookup[0].getValueDecl())) {
656-
auto *D = cast<TypeDecl>(Lookup[0].getValueDecl());
653+
auto buildTypeExpr = [&](TypeDecl *D) -> Expr * {
657654
// FIXME: This is odd.
658655
if (isa<ModuleDecl>(D)) {
659-
return new (Context) DeclRefExpr(D, UDRE->getNameLoc(),
660-
/*Implicit=*/false,
661-
AccessSemantics::Ordinary,
662-
D->getInterfaceType());
656+
return new (Context) DeclRefExpr(
657+
D, UDRE->getNameLoc(),
658+
/*Implicit=*/false, AccessSemantics::Ordinary, D->getInterfaceType());
663659
}
664660

665661
auto *LookupDC = Lookup[0].getDeclContext();
@@ -668,12 +664,19 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
668664
UDRE->getNameLoc(), D, LookupDC,
669665
// It might happen that LookupDC is null if this is checking
670666
// synthesized code, in that case, don't map the type into context,
671-
// but return as is -- the synthesis should ensure the type is correct.
667+
// but return as is -- the synthesis should ensure the type is
668+
// correct.
672669
LookupDC ? LookupDC->mapTypeIntoContext(D->getInterfaceType())
673670
: D->getInterfaceType());
674671
} else {
675672
return TypeExpr::createForDecl(UDRE->getNameLoc(), D, LookupDC);
676673
}
674+
};
675+
676+
// If we have an unambiguous reference to a type decl, form a TypeExpr.
677+
if (Lookup.size() == 1 && UDRE->getRefKind() == DeclRefKind::Ordinary &&
678+
isa<TypeDecl>(Lookup[0].getValueDecl())) {
679+
return buildTypeExpr(cast<TypeDecl>(Lookup[0].getValueDecl()));
677680
}
678681

679682
if (AllDeclRefs) {
@@ -710,6 +713,24 @@ Expr *TypeChecker::resolveDeclRefExpr(UnresolvedDeclRefExpr *UDRE,
710713
});
711714
}
712715

716+
// Filter out macro declarations without `#` if there are valid
717+
// non-macro results.
718+
if (llvm::any_of(ResultValues,
719+
[](const ValueDecl *D) { return !isa<MacroDecl>(D); })) {
720+
ResultValues.erase(
721+
llvm::remove_if(ResultValues,
722+
[](const ValueDecl *D) { return isa<MacroDecl>(D); }),
723+
ResultValues.end());
724+
725+
// If there is only one type reference in results, let's handle
726+
// this in a special way.
727+
if (ResultValues.size() == 1 &&
728+
UDRE->getRefKind() == DeclRefKind::Ordinary &&
729+
isa<TypeDecl>(ResultValues.front())) {
730+
return buildTypeExpr(cast<TypeDecl>(ResultValues.front()));
731+
}
732+
}
733+
713734
return buildRefExpr(ResultValues, DC, UDRE->getNameLoc(),
714735
UDRE->isImplicit(), UDRE->getFunctionRefKind());
715736
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %empty-directory(%t/src)
2+
// RUN: %empty-directory(%t/sdk)
3+
// RUN: split-file %s %t/src
4+
5+
// RUN: %target-swift-frontend -emit-module %t/src/Test.swift \
6+
// RUN: -module-name Test -swift-version 5 -enable-library-evolution \
7+
// RUN: -emit-module-path %t/Test.swiftmodule
8+
9+
// RUN: %target-swift-frontend -typecheck %t/src/main.swift \
10+
// RUN: -module-name main -I %t -verify
11+
12+
// REQUIRES: swift_swift_parser
13+
// REQUIRES: observation
14+
15+
//--- Test.swift
16+
17+
public protocol ObservableConvertibleType {
18+
associatedtype Element
19+
}
20+
21+
public protocol ObservableType : ObservableConvertibleType {}
22+
23+
public class Observable<Element> : ObservableType {
24+
}
25+
26+
extension ObservableType {
27+
public static func empty() -> Observable<Element> { fatalError() }
28+
}
29+
30+
//--- main.swift
31+
import Test
32+
import Observation
33+
34+
extension Observable {
35+
func test() -> Observable<Bool> {
36+
return Observable<Bool>.empty()
37+
}
38+
}

test/Macros/macro_and_typealias.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,11 @@
99
@freestanding(expression) public macro ConcretePrint(_ value: Any) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
1010
@freestanding(expression) public macro MultiPrint(_ value: Any) = #externalMacro(module: "MacroDefinition", type: "PrintMacro")
1111

12-
public struct Printer<Value> {
12+
public struct Printer<Value> { // expected-note {{generic type 'Printer' declared here}}
1313
init(_: (Value) -> Void) {}
1414
}
1515

16-
public struct MultiPrinter<T, U> {
17-
// expected-note@-1 {{'T' declared as parameter to type 'MultiPrinter'}}
18-
// expected-note@-2 {{'U' declared as parameter to type 'MultiPrinter'}}
16+
public struct MultiPrinter<T, U> { // expected-note {{generic type 'MultiPrinter' declared here}}
1917
}
2018

2119
typealias Print = Printer
@@ -34,22 +32,20 @@ struct Test {
3432
}
3533

3634
let _ = Print<Object, Int> {
37-
// expected-error@-1 {{generic type 'Print' specialized with too many type parameters (got 2, but expected 1)}}
35+
// expected-error@-1 {{generic type 'Printer' specialized with too many type parameters (got 2, but expected 1)}}
3836
}
3937

4038
let _ = OtherPrint<Object> { // Ok
4139
compute(root: $0, \.prop)
4240
}
4341

4442
let _ = ConcretePrint<Object> { // expected-error {{cannot specialize non-generic type 'ConcretePrint' (aka 'Printer<Any>')}}
45-
compute(root: $0, \.prop) // expected-error {{value of type 'Any' has no member 'prop'}}
46-
// expected-note@-1 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}
43+
// expected-error@-1 {{cannot infer type of closure parameter '$0' without a type annotation}}
44+
compute(root: $0, \.prop)
4745
}
4846

4947
let _ = MultiPrint<Int>()
50-
// expected-error@-1 {{generic type 'MultiPrint' specialized with too few type parameters (got 1, but expected 2)}}
51-
// expected-error@-2 {{generic parameter 'T' could not be inferred}}
52-
// expected-error@-3 {{generic parameter 'U' could not be inferred}}
48+
// expected-error@-1 {{generic type 'MultiPrinter' specialized with too few type parameters (got 1, but expected 2)}}
5349
}
5450

5551
func compute<R, V>(root: R, _: KeyPath<R, V>) {}

0 commit comments

Comments
 (0)