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
13 changes: 13 additions & 0 deletions include/swift/AST/EducationalNotes.def
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@
EDUCATIONAL_NOTES(unsupported_existential_type,
"associated-type-requirements.md")

EDUCATIONAL_NOTES(cannot_pass_type_to_non_ephemeral, "temporary-pointers.md")
EDUCATIONAL_NOTES(cannot_pass_type_to_non_ephemeral_warning,
"temporary-pointers.md")
EDUCATIONAL_NOTES(cannot_use_inout_non_ephemeral,
"temporary-pointers.md")
EDUCATIONAL_NOTES(cannot_use_inout_non_ephemeral_warning,
"temporary-pointers.md")
EDUCATIONAL_NOTES(cannot_construct_dangling_pointer, "temporary-pointers.md")
EDUCATIONAL_NOTES(cannot_construct_dangling_pointer_warning,
"temporary-pointers.md")



EDUCATIONAL_NOTES(non_nominal_no_initializers, "nominal-types.md")
EDUCATIONAL_NOTES(non_nominal_extension, "nominal-types.md")
EDUCATIONAL_NOTES(associated_type_witness_conform_impossible,
Expand Down
22 changes: 16 additions & 6 deletions include/swift/IDE/CodeCompletion.h
Original file line number Diff line number Diff line change
Expand Up @@ -594,6 +594,7 @@ class CodeCompletionResult {
unsigned SemanticContext : 3;
unsigned NotRecommended : 1;
unsigned NotRecReason : 3;
unsigned IsSystem : 1;

/// The number of bytes to the left of the code completion point that
/// should be erased first if this completion string is inserted in the
Expand Down Expand Up @@ -634,6 +635,7 @@ class CodeCompletionResult {
assert(!isOperator() ||
getOperatorKind() != CodeCompletionOperatorKind::None);
AssociatedKind = 0;
IsSystem = 0;
}

/// Constructs a \c Keyword result.
Expand All @@ -651,6 +653,7 @@ class CodeCompletionResult {
TypeDistance(TypeDistance) {
assert(CompletionString);
AssociatedKind = static_cast<unsigned>(Kind);
IsSystem = 0;
}

/// Constructs a \c Literal result.
Expand All @@ -667,6 +670,7 @@ class CodeCompletionResult {
NumBytesToErase(NumBytesToErase), CompletionString(CompletionString),
TypeDistance(TypeDistance) {
AssociatedKind = static_cast<unsigned>(LiteralKind);
IsSystem = 0;
assert(CompletionString);
}

Expand Down Expand Up @@ -694,6 +698,7 @@ class CodeCompletionResult {
TypeDistance(TypeDistance) {
assert(AssociatedDecl && "should have a decl");
AssociatedKind = unsigned(getCodeCompletionDeclKind(AssociatedDecl));
IsSystem = getDeclIsSystem(AssociatedDecl);
assert(CompletionString);
if (isOperator())
KnownOperatorKind =
Expand All @@ -706,8 +711,8 @@ class CodeCompletionResult {
CodeCompletionResult(SemanticContextKind SemanticContext,
unsigned NumBytesToErase,
CodeCompletionString *CompletionString,
CodeCompletionDeclKind DeclKind, StringRef ModuleName,
bool NotRecommended,
CodeCompletionDeclKind DeclKind, bool IsSystem,
StringRef ModuleName, bool NotRecommended,
CodeCompletionResult::NotRecommendedReason NotRecReason,
StringRef BriefDocComment,
ArrayRef<StringRef> AssociatedUSRs,
Expand All @@ -718,10 +723,10 @@ class CodeCompletionResult {
KnownOperatorKind(unsigned(KnownOperatorKind)),
SemanticContext(unsigned(SemanticContext)),
NotRecommended(NotRecommended), NotRecReason(NotRecReason),
NumBytesToErase(NumBytesToErase), CompletionString(CompletionString),
ModuleName(ModuleName), BriefDocComment(BriefDocComment),
AssociatedUSRs(AssociatedUSRs), DocWords(DocWords),
TypeDistance(TypeDistance) {
IsSystem(IsSystem), NumBytesToErase(NumBytesToErase),
CompletionString(CompletionString), ModuleName(ModuleName),
BriefDocComment(BriefDocComment), AssociatedUSRs(AssociatedUSRs),
DocWords(DocWords), TypeDistance(TypeDistance) {
AssociatedKind = static_cast<unsigned>(DeclKind);
assert(CompletionString);
assert(!isOperator() ||
Expand Down Expand Up @@ -763,6 +768,10 @@ class CodeCompletionResult {
return static_cast<CodeCompletionOperatorKind>(KnownOperatorKind);
}

bool isSystem() const {
return static_cast<bool>(IsSystem);
}

ExpectedTypeRelation getExpectedTypeRelation() const {
return static_cast<ExpectedTypeRelation>(TypeDistance);
}
Expand Down Expand Up @@ -810,6 +819,7 @@ class CodeCompletionResult {
getCodeCompletionOperatorKind(StringRef name);
static CodeCompletionOperatorKind
getCodeCompletionOperatorKind(CodeCompletionString *str);
static bool getDeclIsSystem(const Decl *D);
};

struct CodeCompletionResultSink {
Expand Down
8 changes: 4 additions & 4 deletions lib/AST/GenericSignature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,8 @@ bool GenericSignatureImpl::requiresClass(Type type) {

/// Determine the superclass bound on the given dependent type.
Type GenericSignatureImpl::getSuperclassBound(Type type) {
if (!type->isTypeParameter()) return nullptr;
assert(type->isTypeParameter() &&
"Only type parameters can have superclass requirements");

auto &builder = *getGenericSignatureBuilder();
auto equivClass =
Expand Down Expand Up @@ -457,8 +458,7 @@ GenericSignatureImpl::getConformsTo(Type type) {
}

bool GenericSignatureImpl::conformsToProtocol(Type type, ProtocolDecl *proto) {
// FIXME: Deal with concrete conformances here?
if (!type->isTypeParameter()) return false;
assert(type->isTypeParameter() && "Expected a type parameter");

auto &builder = *getGenericSignatureBuilder();
auto equivClass =
Expand Down Expand Up @@ -562,7 +562,7 @@ bool GenericSignatureImpl::isRequirementSatisfied(Requirement requirement) {
// requirement, but it could also be in terms of concrete types if it has
// been substituted/otherwise 'resolved', so we need to handle both.
auto baseType = canFirstType;
if (canFirstType->isTypeParameter()) {
if (baseType->isTypeParameter()) {
auto directSuperclass = getSuperclassBound(baseType);
if (!directSuperclass)
return false;
Expand Down
14 changes: 11 additions & 3 deletions lib/IDE/CodeCompletion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,10 @@ CodeCompletionResult::getCodeCompletionDeclKind(const Decl *D) {
llvm_unreachable("invalid DeclKind");
}

bool CodeCompletionResult::getDeclIsSystem(const Decl *D) {
return D->getModuleContext()->isSystemModule();
}

void CodeCompletionResult::printPrefix(raw_ostream &OS) const {
llvm::SmallString<64> Prefix;
switch (getKind()) {
Expand Down Expand Up @@ -700,6 +704,8 @@ void CodeCompletionResult::printPrefix(raw_ostream &OS) const {
}
if (NotRecommended)
Prefix.append("/NotRecommended");
if (IsSystem)
Prefix.append("/IsSystem");
if (NumBytesToErase != 0) {
Prefix.append("/Erase[");
Prefix.append(Twine(NumBytesToErase).str());
Expand Down Expand Up @@ -4714,9 +4720,11 @@ class CompletionOverrideLookup : public swift::VisibleDeclConsumer {
else {
auto dist = Ctx.SourceMgr.getByteDistance(
introducerLoc, Ctx.SourceMgr.getCodeCompletionLoc());
Builder.setNumBytesToErase(dist);
Builder.addOverrideKeyword();
Builder.addDeclIntroducer(DeclStr.str().substr(0, NameOffset));
if (dist <= CodeCompletionResult::MaxNumBytesToErase) {
Builder.setNumBytesToErase(dist);
Builder.addOverrideKeyword();
Builder.addDeclIntroducer(DeclStr.str().substr(0, NameOffset));
}
}
}

Expand Down
4 changes: 3 additions & 1 deletion lib/IDE/CodeCompletionCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ static bool readCachedModule(llvm::MemoryBuffer *in,
auto opKind = static_cast<CodeCompletionOperatorKind>(*cursor++);
auto context = static_cast<SemanticContextKind>(*cursor++);
auto notRecommended = static_cast<bool>(*cursor++);
auto isSystem = static_cast<bool>(*cursor++);
auto numBytesToErase = static_cast<unsigned>(*cursor++);
auto oldCursor = cursor;
auto chunkIndex = read32le(cursor);
Expand Down Expand Up @@ -248,7 +249,7 @@ static bool readCachedModule(llvm::MemoryBuffer *in,
CodeCompletionResult *result = nullptr;
if (kind == CodeCompletionResult::Declaration) {
result = new (*V.Sink.Allocator) CodeCompletionResult(
context, numBytesToErase, string, declKind, moduleName,
context, numBytesToErase, string, declKind, isSystem, moduleName,
notRecommended, CodeCompletionResult::NotRecommendedReason::NoReason,
briefDocComment, copyStringArray(*V.Sink.Allocator, assocUSRs),
copyStringPairArray(*V.Sink.Allocator, declKeywords),
Expand Down Expand Up @@ -371,6 +372,7 @@ static void writeCachedModule(llvm::raw_ostream &out,
LE.write(static_cast<uint8_t>(CodeCompletionOperatorKind::None));
LE.write(static_cast<uint8_t>(R->getSemanticContext()));
LE.write(static_cast<uint8_t>(R->isNotRecommended()));
LE.write(static_cast<uint8_t>(R->isSystem()));
LE.write(static_cast<uint8_t>(R->getNumBytesToErase()));
LE.write(
static_cast<uint32_t>(addCompletionString(R->getCompletionString())));
Expand Down
37 changes: 37 additions & 0 deletions lib/IRGen/GenConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,41 @@ llvm::Constant *irgen::emitConstantInt(IRGenModule &IGM,
return llvm::ConstantInt::get(IGM.getLLVMContext(), value);
}

llvm::Constant *irgen::emitConstantZero(IRGenModule &IGM, BuiltinInst *BI) {
assert(IGM.getSILModule().getBuiltinInfo(BI->getName()).ID ==
BuiltinValueKind::ZeroInitializer);

auto helper = [&](CanType astType) -> llvm::Constant * {
if (auto type = astType->getAs<BuiltinIntegerType>()) {
APInt zero(type->getWidth().getLeastWidth(), 0);
return llvm::ConstantInt::get(IGM.getLLVMContext(), zero);
}

if (auto type = astType->getAs<BuiltinFloatType>()) {
const llvm::fltSemantics *sema = nullptr;
switch (type->getFPKind()) {
case BuiltinFloatType::IEEE16: sema = &APFloat::IEEEhalf(); break;
case BuiltinFloatType::IEEE32: sema = &APFloat::IEEEsingle(); break;
case BuiltinFloatType::IEEE64: sema = &APFloat::IEEEdouble(); break;
case BuiltinFloatType::IEEE80: sema = &APFloat::x87DoubleExtended(); break;
case BuiltinFloatType::IEEE128: sema = &APFloat::IEEEquad(); break;
case BuiltinFloatType::PPC128: sema = &APFloat::PPCDoubleDouble(); break;
}
auto zero = APFloat::getZero(*sema);
return llvm::ConstantFP::get(IGM.getLLVMContext(), zero);
}

llvm_unreachable("SIL allowed an unknown type?");
};

if (auto vector = BI->getType().getAs<BuiltinVectorType>()) {
auto zero = helper(vector.getElementType());
return llvm::ConstantVector::getSplat(vector->getNumElements(), zero);
}

return helper(BI->getType().getASTType());
}

llvm::Constant *irgen::emitConstantFP(IRGenModule &IGM, FloatLiteralInst *FLI) {
return llvm::ConstantFP::get(IGM.getLLVMContext(), FLI->getValue());
}
Expand Down Expand Up @@ -94,6 +129,8 @@ static llvm::Constant *emitConstantValue(IRGenModule &IGM, SILValue operand) {
return emitAddrOfConstantString(IGM, SLI);
} else if (auto *BI = dyn_cast<BuiltinInst>(operand)) {
switch (IGM.getSILModule().getBuiltinInfo(BI->getName()).ID) {
case BuiltinValueKind::ZeroInitializer:
return emitConstantZero(IGM, BI);
case BuiltinValueKind::PtrToInt: {
llvm::Constant *ptr = emitConstantValue(IGM, BI->getArguments()[0]);
return llvm::ConstantExpr::getPtrToInt(ptr, IGM.IntPtrTy);
Expand Down
3 changes: 3 additions & 0 deletions lib/IRGen/GenConstant.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ namespace irgen {
/// Construct a ConstantInt from an IntegerLiteralInst.
llvm::Constant *emitConstantInt(IRGenModule &IGM, IntegerLiteralInst *ILI);

/// Construct a zero from a zero intializer BuiltinInst.
llvm::Constant *emitConstantZero(IRGenModule &IGM, BuiltinInst *Bi);

/// Construct a ConstantFP from a FloatLiteralInst.
llvm::Constant *emitConstantFP(IRGenModule &IGM, FloatLiteralInst *FLI);

Expand Down
6 changes: 6 additions & 0 deletions lib/SIL/IR/SILGlobalVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@ bool SILGlobalVariable::isValidStaticInitializerInst(const SILInstruction *I,
case SILInstructionKind::BuiltinInst: {
auto *bi = cast<BuiltinInst>(I);
switch (M.getBuiltinInfo(bi->getName()).ID) {
case BuiltinValueKind::ZeroInitializer: {
auto type = bi->getType().getASTType();
if (auto vector = dyn_cast<BuiltinVectorType>(type))
type = vector.getElementType();
return isa<BuiltinIntegerType>(type) || isa<BuiltinFloatType>(type);
}
case BuiltinValueKind::PtrToInt:
if (isa<LiteralInst>(bi->getArguments()[0]))
return true;
Expand Down
16 changes: 14 additions & 2 deletions lib/SILOptimizer/Differentiation/PullbackEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1331,6 +1331,7 @@ void PullbackEmitter::visitSILInstruction(SILInstruction *inst) {
AllocStackInst *
PullbackEmitter::getArrayAdjointElementBuffer(SILValue arrayAdjoint,
int eltIndex, SILLocation loc) {
auto &ctx = builder.getASTContext();
auto arrayTanType = cast<StructType>(arrayAdjoint->getType().getASTType());
auto arrayType = arrayTanType->getParent()->castTo<BoundGenericStructType>();
auto eltTanType = arrayType->getGenericArgs().front()->getCanonicalType();
Expand All @@ -1340,7 +1341,19 @@ PullbackEmitter::getArrayAdjointElementBuffer(SILValue arrayAdjoint,
auto *arrayTanStructDecl = arrayTanType->getStructOrBoundGenericStruct();
auto subscriptLookup =
arrayTanStructDecl->lookupDirect(DeclBaseName::createSubscript());
auto *subscriptDecl = cast<SubscriptDecl>(subscriptLookup.front());
SubscriptDecl *subscriptDecl = nullptr;
for (auto *candidate : subscriptLookup) {
auto candidateModule = candidate->getModuleContext();
if (candidateModule->getName() == ctx.Id_Differentiation ||
candidateModule->isStdlibModule()) {
assert(!subscriptDecl && "Multiple `Array.TangentVector.subscript`s");
subscriptDecl = cast<SubscriptDecl>(candidate);
#ifdef NDEBUG
break;
#endif
}
}
assert(subscriptDecl && "No `Array.TangentVector.subscript`");
auto *subscriptGetterDecl = subscriptDecl->getAccessor(AccessorKind::Get);
assert(subscriptGetterDecl && "No `Array.TangentVector.subscript` getter");
SILOptFunctionBuilder fb(getContext().getTransform());
Expand All @@ -1352,7 +1365,6 @@ PullbackEmitter::getArrayAdjointElementBuffer(SILValue arrayAdjoint,
subscriptGetterFn->getLoweredFunctionType()->getSubstGenericSignature();
// Apply `Array.TangentVector.subscript.getter` to get array element adjoint
// buffer.
auto &ctx = builder.getASTContext();
// %index_literal = integer_literal $Builtin.IntXX, <index>
auto builtinIntType =
SILType::getPrimitiveObjectType(ctx.getIntDecl()
Expand Down
8 changes: 8 additions & 0 deletions lib/SILOptimizer/SILCombiner/SILCombinerCastVisitors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ SILCombiner::visitThickToObjCMetatypeInst(ThickToObjCMetatypeInst *TTOCMI) {
if (CastOpt.optimizeMetatypeConversion(TTOCMI, MetatypeRepresentation::Thick))
MadeChange = true;

if (auto *OCTTMI = dyn_cast<ObjCToThickMetatypeInst>(TTOCMI->getOperand())) {
TTOCMI->replaceAllUsesWith(OCTTMI->getOperand());
return eraseInstFromFunction(*TTOCMI);
}
return nullptr;
}

Expand All @@ -472,6 +476,10 @@ SILCombiner::visitObjCToThickMetatypeInst(ObjCToThickMetatypeInst *OCTTMI) {
if (CastOpt.optimizeMetatypeConversion(OCTTMI, MetatypeRepresentation::ObjC))
MadeChange = true;

if (auto *TTOCMI = dyn_cast<ThickToObjCMetatypeInst>(OCTTMI->getOperand())) {
OCTTMI->replaceAllUsesWith(TTOCMI->getOperand());
return eraseInstFromFunction(*OCTTMI);
}
return nullptr;
}

Expand Down
9 changes: 9 additions & 0 deletions lib/SILOptimizer/Transforms/DeadCodeElimination.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ namespace {
// FIXME: Reconcile the similarities between this and
// isInstructionTriviallyDead.
static bool seemsUseful(SILInstruction *I) {
// begin_access is defined to have side effects, but this is not relevant for
// DCE.
if (isa<BeginAccessInst>(I))
return false;

if (I->mayHaveSideEffects())
return true;

Expand Down Expand Up @@ -258,6 +263,10 @@ void DCE::markLive(SILFunction &F) {
}
continue;
}
if (auto *endAccess = dyn_cast<EndAccessInst>(&I)) {
addReverseDependency(endAccess->getBeginAccess(), &I);
continue;
}
if (seemsUseful(&I))
markValueLive(&I);
}
Expand Down
2 changes: 1 addition & 1 deletion stdlib/public/core/Slice.swift
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ public struct Slice<Base: Collection> {
///
/// print(singleNonZeroDigits.count)
/// // Prints "9"
/// prints(singleNonZeroDigits.base.count)
/// print(singleNonZeroDigits.base.count)
/// // Prints "10"
/// print(singleDigits == singleNonZeroDigits.base)
/// // Prints "true"
Expand Down
9 changes: 9 additions & 0 deletions test/AutoDiff/stdlib/array.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ var ArrayAutoDiffTests = TestSuite("ArrayAutoDiff")

typealias FloatArrayTan = Array<Float>.TangentVector

extension Array.DifferentiableView {
/// A subscript that always fatal errors.
///
/// The differentiation transform should never emit calls to this.
subscript(alwaysFatalError: Int) -> Element {
fatalError("wrong subscript")
}
}

ArrayAutoDiffTests.test("ArrayIdentity") {
func arrayIdentity(_ x: [Float]) -> [Float] {
return x
Expand Down
Loading