Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,7 @@ private struct DiagnoseDependence {
diagnose(sourceLoc, .lifetime_value_outside_thunk, thunkSelect, function.name)
}
}
diagnoseImplicitFunction()
reportScope()
// Identify the use point.
if let userSourceLoc = operand.instruction.location.sourceLoc {
Expand Down Expand Up @@ -323,6 +324,23 @@ private struct DiagnoseDependence {
}
}
}

func diagnoseImplicitFunction() {
guard let funcLoc = function.location.sourceLoc else {
return
}
if let kindName = {
if function.isInitializer {
return "init"
}
if function.isDeinitializer {
return "deinit"
}
return function.accessorKindName
}() {
diagnose(funcLoc, .implicit_function_note, kindName)
}
}
}

// Identify a best-effort variable declaration based on a defining SIL
Expand Down
12 changes: 12 additions & 0 deletions SwiftCompilerSources/Sources/SIL/Function.swift
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,18 @@ final public class Function : CustomStringConvertible, HasShortDescription, Hash
return StringRef(bridged: bridged.getAccessorName()).string
}

public var isInitializer: Bool {
return bridged.isInitializer()
}

public var isDeinitializer: Bool {
return bridged.isDeinitializer()
}

public var isImplicit: Bool {
return bridged.isImplicit()
}

/// True, if the function runs with a swift 5.1 runtime.
/// Note that this is function specific, because inlinable functions are de-serialized
/// in a client module, which might be compiled with a different deployment target.
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/DiagnosticsSIL.def
Original file line number Diff line number Diff line change
Expand Up @@ -1240,6 +1240,8 @@ NOTE(lifetime_outside_scope_use, none,
NOTE(lifetime_outside_scope_escape, none,
"this use causes the lifetime-dependent value to escape", ())

NOTE(implicit_function_note, none, "error in compiler-generated '%0'", (StringRef))

ERROR(noncopyable_shared_case_block_unimplemented, none,
"matching a non-'Copyable' value using a case label that has multiple patterns is not implemented", ())

Expand Down
3 changes: 3 additions & 0 deletions include/swift/SIL/SILBridging.h
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,9 @@ struct BridgedFunction {
BridgedOwnedString getDebugDescription() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedLocation getLocation() const;
BRIDGED_INLINE bool isAccessor() const;
BRIDGED_INLINE bool isInitializer() const;
BRIDGED_INLINE bool isDeinitializer() const;
BRIDGED_INLINE bool isImplicit() const;
SWIFT_IMPORT_UNSAFE BRIDGED_INLINE BridgedStringRef getAccessorName() const;
BRIDGED_INLINE bool hasOwnership() const;
BRIDGED_INLINE bool hasLoweredAddresses() const;
Expand Down
15 changes: 15 additions & 0 deletions include/swift/SIL/SILBridgingImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,21 @@ BridgedStringRef BridgedFunction::getAccessorName() const {
return accessorKindName(accessorDecl->getAccessorKind());
}

bool BridgedFunction::isInitializer() const {
return getFunction()->getDeclRef().isConstructor();
}

bool BridgedFunction::isDeinitializer() const {
return getFunction()->getDeclRef().isDestructor();
}

bool BridgedFunction::isImplicit() const {
if (auto *funcDecl = getFunction()->getDeclRef().getAbstractFunctionDecl()) {
return funcDecl->isImplicit();
}
return false;
}

bool BridgedFunction::hasOwnership() const { return getFunction()->hasOwnership(); }

bool BridgedFunction::hasLoweredAddresses() const { return getFunction()->getModule().useLoweredAddresses(); }
Expand Down