Skip to content

Commit 2807a17

Browse files
committed
[Type checker SR-899] Warning on missing ".self" for single-parameter functions.
Due to a modeling error in the type checker's folding of type references into type expressions, code such as "strideof(Int)" would be accepted without the required ".self". Commit 4a60b6c fixes the modeling issue but left the historical accepts-invalid; now, diagnose these cases with a warning + Fix-It to ease the transition. Fixes SR-899.
1 parent b7cbfd1 commit 2807a17

File tree

10 files changed

+28
-21
lines changed

10 files changed

+28
-21
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2168,6 +2168,8 @@ ERROR(value_of_module_type,none,
21682168

21692169
ERROR(value_of_metatype_type,none,
21702170
"expected member name or constructor call after type name", ())
2171+
WARNING(warn_value_of_metatype_missing_self,none,
2172+
"missing '.self' for reference to metatype of type %0", (Type))
21712173

21722174
NOTE(add_parens_to_type,none,
21732175
"add arguments after the type to construct a value of the type", ())

lib/Sema/MiscDiagnostics.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -494,13 +494,15 @@ static void diagSyntacticUseRestrictions(TypeChecker &TC, const Expr *E,
494494
return;
495495
}
496496

497-
// FIXME: As a specific hack, we white-list parenthesized
498-
// expressions that are call arguments. This allows some
499-
// ill-formed code to omit ".self" due to a historical bug. We
500-
// keep that code working until we have a decision on SE-0090,
501-
// rather than potentially breaking code twice.
502-
if (isa<ParenExpr>(ParentExpr) && CallArgs.count(ParentExpr) > 0)
497+
// Note: as a specific hack, produce a warning + Fix-It for
498+
// the missing ".self" as the subexpression of a parenthesized
499+
// expression, which is a historical bug.
500+
if (isa<ParenExpr>(ParentExpr) && CallArgs.count(ParentExpr) > 0) {
501+
TC.diagnose(E->getEndLoc(), diag::warn_value_of_metatype_missing_self,
502+
E->getType()->getRValueInstanceType())
503+
.fixItInsertAfter(E->getEndLoc(), ".self");
503504
return;
505+
}
504506
}
505507

506508
// Is this a protocol metatype?

stdlib/private/SwiftPrivateLibcExtras/SwiftPrivateLibcExtras.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ public var _stdlib_FD_SETSIZE: CInt {
4040
public struct _stdlib_fd_set {
4141
var _data: [UInt]
4242
static var _wordBits: Int {
43-
return sizeof(UInt) * 8
43+
return sizeof(UInt.self) * 8
4444
}
4545

4646
public init() {

stdlib/public/SDK/CoreAudio/CoreAudio.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ extension UnsafeBufferPointer {
1717
public init(_ audioBuffer: AudioBuffer) {
1818
self.init(
1919
start: UnsafePointer<Element>(audioBuffer.mData),
20-
count: Int(audioBuffer.mDataByteSize) / strideof(Element))
20+
count: Int(audioBuffer.mDataByteSize) / strideof(Element.self))
2121
}
2222
}
2323

@@ -27,7 +27,7 @@ extension UnsafeMutableBufferPointer {
2727
public init(_ audioBuffer: AudioBuffer) {
2828
self.init(
2929
start: UnsafeMutablePointer<Element>(audioBuffer.mData),
30-
count: Int(audioBuffer.mDataByteSize) / strideof(Element))
30+
count: Int(audioBuffer.mDataByteSize) / strideof(Element.self))
3131
}
3232
}
3333

@@ -40,7 +40,7 @@ extension AudioBuffer {
4040
) {
4141
self.mNumberChannels = UInt32(numberOfChannels)
4242
self.mData = UnsafeMutablePointer<Void>(typedBuffer.baseAddress)
43-
self.mDataByteSize = UInt32(typedBuffer.count * strideof(Element))
43+
self.mDataByteSize = UInt32(typedBuffer.count * strideof(Element.self))
4444
}
4545
}
4646

@@ -50,8 +50,8 @@ extension AudioBufferList {
5050
public static func sizeInBytes(maximumBuffers: Int) -> Int {
5151
_precondition(maximumBuffers >= 1,
5252
"AudioBufferList should contain at least one AudioBuffer")
53-
return sizeof(AudioBufferList) +
54-
(maximumBuffers - 1) * strideof(AudioBuffer)
53+
return sizeof(AudioBufferList.self) +
54+
(maximumBuffers - 1) * strideof(AudioBuffer.self)
5555
}
5656

5757
/// Allocate an `AudioBufferList` with a capacity for the specified number of

stdlib/public/SDK/SceneKit/SceneKit.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,10 +162,10 @@ extension SCNGeometryElement {
162162
primitiveCount = indexCount
163163
}
164164
self.init(
165-
data: NSData(bytes: indices, length: indexCount * sizeof(IndexType)),
165+
data: NSData(bytes: indices, length: indexCount * sizeof(IndexType.self)),
166166
primitiveType: primitiveType,
167167
primitiveCount: primitiveCount,
168-
bytesPerIndex: sizeof(IndexType))
168+
bytesPerIndex: sizeof(IndexType.self))
169169
}
170170
}
171171

stdlib/public/core/Builtin.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ internal func _roundUp<T, DestinationType>(
9898
return UnsafeMutablePointer<DestinationType>(
9999
bitPattern: _roundUpImpl(
100100
UInt(bitPattern: pointer),
101-
toAlignment: alignof(DestinationType))
101+
toAlignment: alignof(DestinationType.self))
102102
).unsafelyUnwrapped
103103
}
104104

stdlib/public/core/HashedCollections.swift.gyb

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2475,14 +2475,14 @@ final internal class _Native${Self}StorageImpl<${TypeParameters}> :
24752475
/// padding to align the start to word alignment.
24762476
internal static func bytesForBitMap(capacity: Int) -> Int {
24772477
let numWords = _UnsafeBitMap.sizeInWords(forSizeInBits: capacity)
2478-
return numWords * strideof(UInt) + alignof(UInt)
2478+
return numWords * strideof(UInt.self) + alignof(UInt.self)
24792479
}
24802480

24812481
/// Returns the bytes necessary to store 'capacity' keys and padding to align
24822482
/// the start to the alignment of the 'Key' type assuming a word aligned base
24832483
/// address.
24842484
internal static func bytesForKeys(capacity: Int) -> Int {
2485-
let padding = max(0, alignof(Key.self) - alignof(UInt))
2485+
let padding = max(0, alignof(Key.self) - alignof(UInt.self))
24862486
return strideof(Key.self) * capacity + padding
24872487
}
24882488

@@ -2492,7 +2492,7 @@ final internal class _Native${Self}StorageImpl<${TypeParameters}> :
24922492
/// address aligned to the maximum of the alignment of the 'Key' type and the
24932493
/// alignment of a word.
24942494
internal static func bytesForValues(capacity: Int) -> Int {
2495-
let maxPrevAlignment = max(alignof(Key.self), alignof(UInt))
2495+
let maxPrevAlignment = max(alignof(Key.self), alignof(UInt.self))
24962496
let padding = max(0, alignof(Value.self) - maxPrevAlignment)
24972497
return strideof(Value.self) * capacity + padding
24982498
}
@@ -2540,7 +2540,7 @@ final internal class _Native${Self}StorageImpl<${TypeParameters}> :
25402540
let bitMapSizeInBytes =
25412541
_unsafeMultiply(
25422542
_UnsafeBitMap.sizeInWords(forSizeInBits: _capacity),
2543-
strideof(UInt))
2543+
strideof(UInt.self))
25442544
let start =
25452545
UnsafeMutablePointer<UInt8>(_initializedHashtableEntriesBitMapStorage)
25462546
+ bitMapSizeInBytes

stdlib/public/core/ManagedBuffer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ public struct ManagedBufferPointer<Value, Element> : Equatable {
248248
/// idea to store this information in the "value" area when
249249
/// an instance is created.
250250
public var capacity: Int {
251-
return (_capacityInBytes &- _My._elementOffset) / strideof(Element)
251+
return (_capacityInBytes &- _My._elementOffset) / strideof(Element.self)
252252
}
253253

254254
/// Call `body` with an `UnsafeMutablePointer` to the stored

stdlib/public/core/Runtime.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ func _rawPointerToString(_ value: Builtin.RawPointer) -> String {
474474
radix: 16,
475475
uppercase: false
476476
)
477-
for _ in 0..<(2 * sizeof(UnsafePointer<Void>) - result.utf16.count) {
477+
for _ in 0..<(2 * sizeof(UnsafePointer<Void>.self) - result.utf16.count) {
478478
result = "0" + result
479479
}
480480
return "0x" + result

test/Constraints/metatypes.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,6 @@ struct S {}
1313

1414
let test5 : S.Type = S.self
1515
let test6 : AnyClass = S.self // expected-error {{cannot convert value of type 'S.Type' to specified type 'AnyClass' (aka 'AnyObject.Type')}}
16+
17+
func acceptMeta<T>(_ meta: T.Type) { }
18+
acceptMeta(A) // expected-warning{{missing '.self' for reference to metatype of type 'A'}}{{13-13=.self}}

0 commit comments

Comments
 (0)