Skip to content

Commit

Permalink
Merge pull request #509 from swiftwasm/master
Browse files Browse the repository at this point in the history
[pull] swiftwasm from master
  • Loading branch information
pull[bot] authored Mar 27, 2020
2 parents 882f797 + df5ba9c commit 74f98bd
Show file tree
Hide file tree
Showing 44 changed files with 1,303 additions and 147 deletions.
21 changes: 10 additions & 11 deletions include/swift/AST/DeclContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -552,31 +552,30 @@ class alignas(1 << DeclContextAlignInBits) DeclContext {
///
/// \param lookupKind The kind of lookup to perform.
///
/// \param diagnostics If non-null, will be populated with the set of
/// diagnostics that should be emitted for this declaration context.
/// FIXME: This likely makes more sense on IterableDeclContext or
/// something similar.
SmallVector<ProtocolDecl *, 2>
getLocalProtocols(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All,
SmallVectorImpl<ConformanceDiagnostic> *diagnostics
= nullptr) const;
= ConformanceLookupKind::All) const;

/// Retrieve the set of protocol conformances associated with this
/// declaration context.
///
/// \param lookupKind The kind of lookup to perform.
///
/// \param diagnostics If non-null, will be populated with the set of
/// diagnostics that should be emitted for this declaration context.
///
/// FIXME: This likely makes more sense on IterableDeclContext or
/// something similar.
SmallVector<ProtocolConformance *, 2>
getLocalConformances(ConformanceLookupKind lookupKind
= ConformanceLookupKind::All,
SmallVectorImpl<ConformanceDiagnostic> *diagnostics
= nullptr) const;
= ConformanceLookupKind::All) const;

/// Retrieve diagnostics discovered while expanding conformances for this
/// declaration context. This operation then removes those diagnostics from
/// consideration, so subsequent calls to this function with the same
/// declaration context that have not had any new extensions bound
/// will see an empty array.
SmallVector<ConformanceDiagnostic, 4>
takeConformanceDiagnostics() const;

/// Retrieves a list of separately imported overlays which are shadowing
/// \p declaring. If any \p overlays are returned, qualified lookups into
Expand Down
20 changes: 20 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1200,8 +1200,16 @@ ERROR(c_function_pointer_from_method,none,
ERROR(c_function_pointer_from_generic_function,none,
"a C function pointer cannot be formed from a reference to a generic "
"function", ())
ERROR(unsupported_linear_to_differentiable_conversion,none,
"conversion from '@differentiable(linear)' to '@differentiable' is not "
"yet supported", ())
ERROR(invalid_autoclosure_forwarding,none,
"add () to forward @autoclosure parameter", ())
ERROR(invalid_differentiable_function_conversion_expr,none,
"a '@differentiable%select{|(linear)}0' function can only be formed from "
"a reference to a 'func' or a literal closure", (bool))
NOTE(invalid_differentiable_function_conversion_parameter,none,
"did you mean to take a '%0' closure?", (StringRef))
ERROR(invalid_autoclosure_pointer_conversion,none,
"cannot perform pointer conversion of value of type %0 to autoclosure "
"result type %1",
Expand Down Expand Up @@ -4016,6 +4024,18 @@ ERROR(opaque_type_in_protocol_requirement,none,
ERROR(attr_only_on_parameters_of_differentiable,none,
"'%0' may only be used on parameters of '@differentiable' function "
"types", (StringRef))
ERROR(differentiable_function_type_invalid_parameter,none,
"parameter type '%0' does not conform to 'Differentiable'"
"%select{| and satisfy '%0 == %0.TangentVector'}1, but the enclosing "
"function type is '@differentiable%select{|(linear)}1'"
"%select{|; did you want to add '@noDerivative' to this parameter?}2",
(StringRef, /*tangentVectorEqualsSelf*/ bool,
/*hasValidDifferentiabilityParameter*/ bool))
ERROR(differentiable_function_type_invalid_result,none,
"result type '%0' does not conform to 'Differentiable'"
"%select{| and satisfy '%0 == %0.TangentVector'}1, but the enclosing "
"function type is '@differentiable%select{|(linear)}1'",
(StringRef, bool))

// SIL
ERROR(opened_non_protocol,none,
Expand Down
55 changes: 55 additions & 0 deletions include/swift/AST/Expr.h
Original file line number Diff line number Diff line change
Expand Up @@ -2966,6 +2966,61 @@ class UnevaluatedInstanceExpr : public ImplicitConversionExpr {
}
};

class DifferentiableFunctionExpr : public ImplicitConversionExpr {
public:
DifferentiableFunctionExpr(Expr *subExpr, Type ty)
: ImplicitConversionExpr(ExprKind::DifferentiableFunction, subExpr, ty) {}

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::DifferentiableFunction;
}
};

class LinearFunctionExpr : public ImplicitConversionExpr {
public:
LinearFunctionExpr(Expr *subExpr, Type ty)
: ImplicitConversionExpr(ExprKind::LinearFunction, subExpr, ty) {}

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::LinearFunction;
}
};

class DifferentiableFunctionExtractOriginalExpr
: public ImplicitConversionExpr {
public:
DifferentiableFunctionExtractOriginalExpr(Expr *subExpr, Type ty)
: ImplicitConversionExpr(ExprKind::DifferentiableFunctionExtractOriginal,
subExpr, ty) {}

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::DifferentiableFunctionExtractOriginal;
}
};

class LinearFunctionExtractOriginalExpr : public ImplicitConversionExpr {
public:
LinearFunctionExtractOriginalExpr(Expr *subExpr, Type ty)
: ImplicitConversionExpr(ExprKind::LinearFunctionExtractOriginal,
subExpr, ty) {}

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::LinearFunctionExtractOriginal;
}
};

class LinearToDifferentiableFunctionExpr : public ImplicitConversionExpr {
public:
LinearToDifferentiableFunctionExpr(Expr *subExpr, Type ty)
: ImplicitConversionExpr(
ExprKind::LinearToDifferentiableFunction, subExpr, ty) {}

static bool classof(const Expr *E) {
return E->getKind() == ExprKind::LinearToDifferentiableFunction;
}
};


/// Use an opaque type to abstract a value of the underlying concrete type.
class UnderlyingToOpaqueExpr : public ImplicitConversionExpr {
public:
Expand Down
7 changes: 6 additions & 1 deletion include/swift/AST/ExprNodes.def
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,12 @@ ABSTRACT_EXPR(ImplicitConversion, Expr)
EXPR(ForeignObjectConversion, ImplicitConversionExpr)
EXPR(UnevaluatedInstance, ImplicitConversionExpr)
EXPR(UnderlyingToOpaque, ImplicitConversionExpr)
EXPR_RANGE(ImplicitConversion, Load, UnderlyingToOpaque)
EXPR(DifferentiableFunction, ImplicitConversionExpr)
EXPR(LinearFunction, ImplicitConversionExpr)
EXPR(DifferentiableFunctionExtractOriginal, ImplicitConversionExpr)
EXPR(LinearFunctionExtractOriginal, ImplicitConversionExpr)
EXPR(LinearToDifferentiableFunction, ImplicitConversionExpr)
EXPR_RANGE(ImplicitConversion, Load, LinearToDifferentiableFunction)
ABSTRACT_EXPR(ExplicitCast, Expr)
ABSTRACT_EXPR(CheckedCast, ExplicitCastExpr)
EXPR(ForcedCheckedCast, CheckedCastExpr)
Expand Down
33 changes: 33 additions & 0 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -2185,6 +2185,39 @@ class ClosureHasExplicitResultRequest
bool isCached() const { return true; }
};

using ProtocolConformanceLookupResult = SmallVector<ProtocolConformance *, 2>;
void simple_display(llvm::raw_ostream &out, ConformanceLookupKind kind);

/// Lookup and expand all conformances in the given context.
///
/// This request specifically accomodates algorithms for retrieving all
/// conformances in the primary, even those that are unstated in source but
/// are implied by other conformances, inherited from other types, or synthesized
/// by the compiler. A simple case of this is the following:
///
/// \code
/// protocol P {}
/// protocol Q : P {}
/// extension T : Q {}
/// \endcode
///
/// Here, a conformance to \c Q has been stated, but a conformance to \c P
/// must also be reported so it can be checked as well.
class LookupAllConformancesInContextRequest :
public SimpleRequest<LookupAllConformancesInContextRequest,
ProtocolConformanceLookupResult(const DeclContext *),
CacheKind::Uncached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

// Evaluation.
llvm::Expected<ProtocolConformanceLookupResult>
evaluate(Evaluator &evaluator, const DeclContext *DC) const;
};

// Allow AnyValue to compare two Type values, even though Type doesn't
// support ==.
template<>
Expand Down
3 changes: 3 additions & 0 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -236,3 +236,6 @@ SWIFT_REQUEST(TypeChecker, ScopedImportLookupRequest,
ArrayRef<ValueDecl *>(ImportDecl *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, ClosureHasExplicitResultRequest,
bool(ClosureExpr *), Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, LookupAllConformancesInContextRequest,
ProtocolConformanceLookupResult(const DeclContext *),
Uncached, NoLocationInfo)
8 changes: 8 additions & 0 deletions include/swift/SIL/SILBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -2189,6 +2189,14 @@ class SILBuilder {
ExtracteeType));
}

DifferentiableFunctionExtractInst *
createDifferentiableFunctionExtractOriginal(SILLocation Loc,
SILValue TheFunction) {
return insert(new (getModule()) DifferentiableFunctionExtractInst(
getModule(), getSILDebugLocation(Loc),
NormalDifferentiableFunctionTypeComponent::Original, TheFunction));
}

LinearFunctionExtractInst *createLinearFunctionExtract(
SILLocation Loc, LinearDifferentiableFunctionTypeComponent Extractee,
SILValue TheFunction) {
Expand Down
2 changes: 2 additions & 0 deletions include/swift/SILOptimizer/PassManager/Passes.def
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,8 @@ PASS(PredictableMemoryAccessOptimizations, "predictable-memaccess-opts",
"Predictable Memory Access Optimizations for Diagnostics")
PASS(PredictableDeadAllocationElimination, "predictable-deadalloc-elim",
"Eliminate dead temporary allocations after diagnostics")
PASS(RedundantPhiElimination, "redundant-phi-elimination",
"Redundant Phi Block Argument Elimination")
PASS(ReleaseDevirtualizer, "release-devirtualizer",
"SIL release Devirtualization")
PASS(RetainSinking, "retain-sinking",
Expand Down
28 changes: 28 additions & 0 deletions lib/AST/ASTDumper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2354,6 +2354,34 @@ class PrintExpr : public ExprVisitor<PrintExpr> {
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitDifferentiableFunctionExpr(DifferentiableFunctionExpr *E) {
printCommon(E, "differentiable_function") << '\n';
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitLinearFunctionExpr(LinearFunctionExpr *E) {
printCommon(E, "linear_function") << '\n';
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitDifferentiableFunctionExtractOriginalExpr(
DifferentiableFunctionExtractOriginalExpr *E) {
printCommon(E, "differentiable_function_extract_original") << '\n';
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitLinearFunctionExtractOriginalExpr(
LinearFunctionExtractOriginalExpr *E) {
printCommon(E, "linear_function_extract_original") << '\n';
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}
void visitLinearToDifferentiableFunctionExpr(
LinearToDifferentiableFunctionExpr *E) {
printCommon(E, "linear_to_differentiable_function") << '\n';
printRec(E->getSubExpr());
PrintWithColorRAII(OS, ParenthesisColor) << ')';
}

void visitInOutExpr(InOutExpr *E) {
printCommon(E, "inout_expr") << '\n';
Expand Down
10 changes: 10 additions & 0 deletions lib/AST/Expr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,11 @@ ConcreteDeclRef Expr::getReferencedDecl(bool stopAtParenExpr) const {
PASS_THROUGH_REFERENCE(PointerToPointer, getSubExpr);
PASS_THROUGH_REFERENCE(ForeignObjectConversion, getSubExpr);
PASS_THROUGH_REFERENCE(UnevaluatedInstance, getSubExpr);
PASS_THROUGH_REFERENCE(DifferentiableFunction, getSubExpr);
PASS_THROUGH_REFERENCE(LinearFunction, getSubExpr);
PASS_THROUGH_REFERENCE(DifferentiableFunctionExtractOriginal, getSubExpr);
PASS_THROUGH_REFERENCE(LinearFunctionExtractOriginal, getSubExpr);
PASS_THROUGH_REFERENCE(LinearToDifferentiableFunction, getSubExpr);
PASS_THROUGH_REFERENCE(BridgeToObjC, getSubExpr);
PASS_THROUGH_REFERENCE(BridgeFromObjC, getSubExpr);
PASS_THROUGH_REFERENCE(ConditionalBridgeFromObjC, getSubExpr);
Expand Down Expand Up @@ -667,6 +672,11 @@ bool Expr::canAppendPostfixExpression(bool appendingPostfixOperator) const {
case ExprKind::PointerToPointer:
case ExprKind::ForeignObjectConversion:
case ExprKind::UnevaluatedInstance:
case ExprKind::DifferentiableFunction:
case ExprKind::LinearFunction:
case ExprKind::DifferentiableFunctionExtractOriginal:
case ExprKind::LinearFunctionExtractOriginal:
case ExprKind::LinearToDifferentiableFunction:
case ExprKind::EnumIsCase:
case ExprKind::ConditionalBridgeFromObjC:
case ExprKind::BridgeFromObjC:
Expand Down
44 changes: 44 additions & 0 deletions lib/AST/GenericSignatureBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5070,6 +5070,50 @@ class GenericSignatureBuilder::InferRequirementsWalker : public TypeWalker {
return Action::Continue;
}

// Infer requirements from `@differentiable` or `@differentiable(linear)`
// function types.
// For all non-`@noDerivative` parameter and result types:
// - `@differentiable`: add `T: Differentiable` requirement.
// - `@differentiable(linear)`: add
// `T: Differentiable`, `T == T.TangentVector` requirements.
if (auto *fnTy = ty->getAs<AnyFunctionType>()) {
auto &ctx = Builder.getASTContext();
auto *differentiableProtocol =
ctx.getProtocol(KnownProtocolKind::Differentiable);
if (differentiableProtocol && fnTy->isDifferentiable()) {
auto addConformanceConstraint = [&](Type type, ProtocolDecl *protocol) {
Requirement req(RequirementKind::Conformance, type,
protocol->getDeclaredType());
Builder.addRequirement(req, source, nullptr);
};
auto addSameTypeConstraint = [&](Type firstType,
AssociatedTypeDecl *assocType) {
auto *protocol = assocType->getProtocol();
auto conf = Builder.lookupConformance(CanType(), firstType, protocol);
auto secondType = conf.getAssociatedType(
firstType, assocType->getDeclaredInterfaceType());
Requirement req(RequirementKind::SameType, firstType, secondType);
Builder.addRequirement(req, source, nullptr);
};
auto *tangentVectorAssocType =
differentiableProtocol->getAssociatedType(ctx.Id_TangentVector);
auto addRequirements = [&](Type type, bool isLinear) {
addConformanceConstraint(type, differentiableProtocol);
if (isLinear)
addSameTypeConstraint(type, tangentVectorAssocType);
};
auto constrainParametersAndResult = [&](bool isLinear) {
for (auto &param : fnTy->getParams())
if (!param.isNoDerivative())
addRequirements(param.getPlainType(), isLinear);
addRequirements(fnTy->getResult(), isLinear);
};
// Add requirements.
constrainParametersAndResult(fnTy->getDifferentiabilityKind() ==
DifferentiabilityKind::Linear);
}
}

if (!ty->isSpecialized())
return Action::Continue;

Expand Down
7 changes: 4 additions & 3 deletions lib/AST/Module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2068,9 +2068,10 @@ SPIGroupsRequest::evaluate(Evaluator &evaluator, const Decl *decl) const {

// Then in the extended nominal type.
if (auto extension = dyn_cast<ExtensionDecl>(decl)) {
auto extended = extension->getExtendedNominal();
auto extSPIs = extended->getSPIGroups();
if (!extSPIs.empty()) return extSPIs;
if (auto extended = extension->getExtendedNominal()) {
auto extSPIs = extended->getSPIGroups();
if (!extSPIs.empty()) return extSPIs;
}
}

// And finally in the parent context.
Expand Down
Loading

0 comments on commit 74f98bd

Please sign in to comment.