Skip to content

Commit c7813eb

Browse files
committed
---
yaml --- r: 349365 b: refs/heads/master-next c: 0d74b5c h: refs/heads/master i: 349363: 1d90297
1 parent 587cec0 commit c7813eb

File tree

8 files changed

+131
-60
lines changed

8 files changed

+131
-60
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
refs/heads/master: 3574c513bbc5578dd9346b4ea9ab5995c5927bb5
3-
refs/heads/master-next: 4e4836d708dc55bc1b7926a5983977890d88af7a
3+
refs/heads/master-next: 0d74b5c71c410ac59b5a77c31620a5fe7e4ab628
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea
66
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-b: 66d897bfcf64a82cb9a87f5e663d889189d06d07

branches/master-next/include/swift/AST/DiagnosticsSema.def

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ ERROR(could_not_find_value_member,none,
8181
ERROR(could_not_find_value_member_corrected,none,
8282
"value of type %0 has no member %1; did you mean %2?",
8383
(Type, DeclName, DeclName))
84+
ERROR(could_not_find_value_dynamic_member_corrected,none,
85+
"value of type %0 has no dynamic member %2 using key path from root type %1; did you mean %3?",
86+
(Type, Type, DeclName, DeclName))
87+
ERROR(could_not_find_value_dynamic_member,none,
88+
"value of type %0 has no dynamic member %2 using key path from root type %1",
89+
(Type, Type, DeclName))
90+
8491
ERROR(could_not_find_type_member,none,
8592
"type %0 has no member %1", (Type, DeclName))
8693
ERROR(could_not_find_type_member_corrected,none,

branches/master-next/lib/Sema/CSDiagnostics.cpp

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,8 +2258,8 @@ bool MissingMemberFailure::diagnoseAsError() {
22582258
};
22592259

22602260
TypoCorrectionResults corrections(TC, getName(), nameLoc);
2261-
auto tryTypoCorrection = [&] {
2262-
TC.performTypoCorrection(getDC(), DeclRefKind::Ordinary, baseType,
2261+
auto tryTypoCorrection = [&] (Type type) {
2262+
TC.performTypoCorrection(getDC(), DeclRefKind::Ordinary, type,
22632263
defaultMemberLookupOptions, corrections);
22642264
};
22652265

@@ -2279,7 +2279,7 @@ bool MissingMemberFailure::diagnoseAsError() {
22792279
.highlight(baseExpr->getSourceRange());
22802280
} else if (auto metatypeTy = baseType->getAs<MetatypeType>()) {
22812281
auto instanceTy = metatypeTy->getInstanceType();
2282-
tryTypoCorrection();
2282+
tryTypoCorrection(baseType);
22832283

22842284
if (DeclName rightName =
22852285
findCorrectEnumCaseName(instanceTy, corrections, getName())) {
@@ -2323,18 +2323,46 @@ bool MissingMemberFailure::diagnoseAsError() {
23232323
.fixItInsertAfter(baseExpr->getEndLoc(), " as AnyObject)");
23242324
return true;
23252325
}
2326-
2327-
tryTypoCorrection();
2328-
2329-
if (auto correction = corrections.claimUniqueCorrection()) {
2330-
auto diagnostic = emitDiagnostic(
2331-
anchor->getLoc(), diag::could_not_find_value_member_corrected,
2332-
baseType, getName(), correction->CorrectedName);
2333-
diagnostic.highlight(baseExpr->getSourceRange())
2334-
.highlight(nameLoc.getSourceRange());
2335-
correction->addFixits(diagnostic);
2326+
2327+
tryTypoCorrection(baseType);
2328+
2329+
// If locator points to the member found via key path dynamic member lookup,
2330+
// we provide a custom diagnostic and emit typo corrections for the wrapper type too.
2331+
if (getLocator()->isForKeyPathDynamicMemberLookup()) {
2332+
auto baseExprType = getType(baseExpr)->getWithoutSpecifierType();
2333+
2334+
tryTypoCorrection(baseExprType);
2335+
2336+
if (auto correction = corrections.claimUniqueCorrection()) {
2337+
auto diagnostic = emitDiagnostic(
2338+
anchor->getLoc(),
2339+
diag::could_not_find_value_dynamic_member_corrected,
2340+
baseExprType, baseType, getName(),
2341+
correction->CorrectedName);
2342+
diagnostic.highlight(baseExpr->getSourceRange())
2343+
.highlight(nameLoc.getSourceRange());
2344+
correction->addFixits(diagnostic);
2345+
} else {
2346+
auto diagnostic = emitDiagnostic(
2347+
anchor->getLoc(),
2348+
diag::could_not_find_value_dynamic_member,
2349+
baseExprType, baseType, getName());
2350+
diagnostic.highlight(baseExpr->getSourceRange())
2351+
.highlight(nameLoc.getSourceRange());
2352+
}
23362353
} else {
2337-
emitBasicError(baseType);
2354+
if (auto correction = corrections.claimUniqueCorrection()) {
2355+
auto diagnostic = emitDiagnostic(
2356+
anchor->getLoc(),
2357+
diag::could_not_find_value_member_corrected,
2358+
baseType, getName(),
2359+
correction->CorrectedName);
2360+
diagnostic.highlight(baseExpr->getSourceRange())
2361+
.highlight(nameLoc.getSourceRange());
2362+
correction->addFixits(diagnostic);
2363+
} else {
2364+
emitBasicError(baseType);
2365+
}
23382366
}
23392367
}
23402368

branches/master-next/stdlib/public/Darwin/Foundation/String.swift

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,28 @@ extension Substring : _ObjectiveCBridgeable {
9696
}
9797

9898
extension String: CVarArg {}
99+
100+
/*
101+
This is on NSObject so that the stdlib can call it in StringBridge.swift
102+
without having to synthesize a receiver (e.g. lookup a class or allocate)
103+
104+
In the future (once the Foundation overlay can know about SmallString), we
105+
should move the caller of this method up into the overlay and avoid this
106+
indirection.
107+
*/
108+
private extension NSObject {
109+
// The ObjC selector has to start with "new" to get ARC to not autorelease
110+
@_effects(releasenone)
111+
@objc(newTaggedNSStringWithASCIIBytes_:length_:)
112+
func createTaggedString(bytes: UnsafePointer<UInt8>,
113+
count: Int) -> AnyObject? {
114+
//TODO: update this to use _CFStringCreateTaggedPointerString once we can
115+
return CFStringCreateWithBytes(
116+
kCFAllocatorSystemDefault,
117+
bytes,
118+
count,
119+
CFStringBuiltInEncodings.UTF8.rawValue,
120+
false
121+
) as NSString as NSString? //just "as AnyObject" inserts unwanted bridging
122+
}
123+
}

branches/master-next/stdlib/public/SwiftShims/CoreFoundationShims.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,17 @@ namespace swift { extern "C" {
2828

2929
#ifdef __OBJC2__
3030
#if __LLP64__
31-
typedef unsigned long long _swift_shims_CFTypeID;
3231
typedef unsigned long long _swift_shims_CFHashCode;
3332
typedef signed long long _swift_shims_CFIndex;
3433
#else
35-
typedef unsigned long _swift_shims_CFTypeID;
3634
typedef unsigned long _swift_shims_CFHashCode;
3735
typedef signed long _swift_shims_CFIndex;
3836
#endif
3937

40-
typedef id _swift_shims_CFStringRef;
41-
typedef __swift_uint32_t _swift_shims_CFStringEncoding;
42-
4338
// Consider creating SwiftMacTypes.h for these
4439
typedef unsigned char _swift_shims_Boolean;
4540
typedef __swift_uint8_t _swift_shims_UInt8;
46-
47-
SWIFT_RUNTIME_STDLIB_API
48-
__attribute__((ns_returns_retained))
49-
_swift_shims_CFStringRef _Nonnull _swift_stdlib_CFStringCreateWithBytes(
50-
const void * _Nullable unused,
51-
const __swift_uint8_t *_Nonnull bytes, _swift_shims_CFIndex numBytes,
52-
_swift_shims_CFStringEncoding encoding,
53-
_swift_shims_Boolean isExternalRepresentation);
41+
typedef __swift_uint32_t _swift_shims_CFStringEncoding;
5442

5543
SWIFT_RUNTIME_STDLIB_API
5644
__swift_uint8_t _swift_stdlib_isNSString(id _Nonnull obj);

branches/master-next/stdlib/public/core/StringBridge.swift

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ internal typealias _CocoaString = AnyObject
5858
options: UInt,
5959
range: _SwiftNSRange,
6060
locale: AnyObject?) -> Int
61+
62+
@objc(newTaggedNSStringWithASCIIBytes_:length_:)
63+
func createTaggedString(bytes: UnsafePointer<UInt8>,
64+
count: Int) -> AnyObject?
6165
}
6266

6367
/*
@@ -410,19 +414,28 @@ extension String {
410414
}
411415
}
412416

417+
@_effects(releasenone)
418+
private func _createNSString(
419+
_ receiver: _StringSelectorHolder,
420+
_ ptr: UnsafePointer<UInt8>,
421+
_ count: Int,
422+
_ encoding: UInt32
423+
) -> AnyObject? {
424+
return receiver.createTaggedString(bytes: ptr, count: count)
425+
}
426+
413427
@_effects(releasenone)
414428
private func _createCFString(
415429
_ ptr: UnsafePointer<UInt8>,
416430
_ count: Int,
417431
_ encoding: UInt32
418-
) -> AnyObject {
419-
return _swift_stdlib_CFStringCreateWithBytes(
420-
nil, //ignored in the shim for perf reasons
432+
) -> AnyObject? {
433+
return _createNSString(
434+
unsafeBitCast(__StringStorage.self as AnyClass, to: _StringSelectorHolder.self),
421435
ptr,
422436
count,
423-
kCFStringEncodingUTF8,
424-
0
425-
) as AnyObject
437+
encoding
438+
)
426439
}
427440

428441
extension String {
@@ -431,13 +444,14 @@ extension String {
431444
func _bridgeToObjectiveCImpl() -> AnyObject {
432445
// Smol ASCII a) may bridge to tagged pointers, b) can't contain a BOM
433446
if _guts.isSmallASCII {
434-
return _guts.asSmall.withUTF8 { bufPtr in
447+
let maybeTagged = _guts.asSmall.withUTF8 { bufPtr in
435448
return _createCFString(
436449
bufPtr.baseAddress._unsafelyUnwrappedUnchecked,
437450
bufPtr.count,
438451
kCFStringEncodingUTF8
439452
)
440453
}
454+
if let tagged = maybeTagged { return tagged }
441455
}
442456
if _guts.isSmall {
443457
// We can't form a tagged pointer String, so grow to a non-small String,

branches/master-next/stdlib/public/stubs/FoundationHelpers.mm

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,13 @@
2525

2626
using namespace swift;
2727

28-
template <class FromTy> struct DestType;
29-
30-
#define BRIDGE_TYPE(FROM, TO) \
31-
template <> struct DestType<FROM> { using type = TO; }
32-
33-
BRIDGE_TYPE(_swift_shims_CFStringRef, CFStringRef);
34-
BRIDGE_TYPE(_swift_shims_CFStringEncoding, CFStringEncoding);
35-
BRIDGE_TYPE(CFStringRef, _swift_shims_CFStringRef);
36-
37-
template <class FromTy>
38-
static typename DestType<FromTy>::type cast(FromTy value) {
39-
return (typename DestType<FromTy>::type) value;
40-
}
41-
4228
__swift_uint8_t
4329
swift::_swift_stdlib_isNSString(id obj) {
4430
//TODO: we can likely get a small perf win by using _NSIsNSString on
4531
//sufficiently new OSs
4632
return CFGetTypeID((CFTypeRef)obj) == CFStringGetTypeID() ? 1 : 0;
4733
}
4834

49-
_swift_shims_CFStringRef
50-
swift::_swift_stdlib_CFStringCreateWithBytes(
51-
const void *unused, const uint8_t *bytes,
52-
_swift_shims_CFIndex numBytes, _swift_shims_CFStringEncoding encoding,
53-
_swift_shims_Boolean isExternalRepresentation) {
54-
assert(unused == NULL);
55-
return cast(CFStringCreateWithBytes(kCFAllocatorSystemDefault, bytes, numBytes,
56-
cast(encoding),
57-
isExternalRepresentation));
58-
}
59-
6035
extern "C" CFHashCode CFStringHashCString(const uint8_t *bytes, CFIndex len);
6136
extern "C" CFHashCode CFStringHashNSString(id str);
6237

branches/master-next/test/attr/attr_dynamic_member_lookup.swift

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,3 +688,37 @@ func invalid_refs_through_dynamic_lookup() {
688688
_ = lens.baz("hello") // expected-error {{dynamic key path member lookup cannot refer to static method 'baz'}}
689689
}
690690
}
691+
692+
// SR-10597
693+
694+
final class SR10597 {
695+
}
696+
697+
@dynamicMemberLookup
698+
struct SR10597_W<T> {
699+
var obj: T
700+
init(_ obj: T) { self.obj = obj }
701+
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
702+
return obj[keyPath: member]
703+
}
704+
var wooo: SR10597 { SR10597() } // expected-note {{declared here}}
705+
}
706+
707+
_ = SR10597_W<SR10597>(SR10597()).wooooo // expected-error {{value of type 'SR10597_W<SR10597>' has no dynamic member 'wooooo' using key path from root type 'SR10597'; did you mean 'wooo'?}}
708+
_ = SR10597_W<SR10597>(SR10597()).bla // expected-error {{value of type 'SR10597_W<SR10597>' has no dynamic member 'bla' using key path from root type 'SR10597'}}
709+
710+
final class SR10597_1 {
711+
var woo: Int? // expected-note 2 {{'woo' declared here}}
712+
}
713+
714+
@dynamicMemberLookup
715+
struct SR10597_1_W<T> {
716+
var obj: T
717+
init(_ obj: T) { self.obj = obj }
718+
subscript<U>(dynamicMember member: KeyPath<T, U>) -> U {
719+
return obj[keyPath: member]
720+
}
721+
}
722+
723+
_ = SR10597_1_W<SR10597_1>(SR10597_1()).wooo // expected-error {{value of type 'SR10597_1_W<SR10597_1>' has no dynamic member 'wooo' using key path from root type 'SR10597_1'; did you mean 'woo'?}}
724+
_ = SR10597_1_W<SR10597_1>(SR10597_1()).bla // expected-error {{value of type 'SR10597_1_W<SR10597_1>' has no dynamic member 'bla' using key path from root type 'SR10597_1'}}

0 commit comments

Comments
 (0)