Skip to content

Commit

Permalink
Merge pull request #515 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 28, 2020
2 parents 74f98bd + bbf94fb commit 1b79306
Show file tree
Hide file tree
Showing 171 changed files with 5,788 additions and 2,313 deletions.
10 changes: 9 additions & 1 deletion docs/ABI/Mangling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,10 @@ Types
FUNCTION-KIND ::= 'C' // C function pointer type
FUNCTION-KIND ::= 'A' // @auto_closure function type (escaping)
FUNCTION-KIND ::= 'E' // function type (noescape)
FUNCTION-KIND ::= 'F' // @differentiable function type
FUNCTION-KIND ::= 'G' // @differentiable function type (escaping)
FUNCTION-KIND ::= 'H' // @differentiable(linear) function type
FUNCTION-KIND ::= 'I' // @differentiable(linear) function type (escaping)

function-signature ::= params-type params-type throws? // results and parameters

Expand Down Expand Up @@ -585,14 +589,18 @@ mangled in to disambiguate.
impl-function-type ::= type* 'I' FUNC-ATTRIBUTES '_'
impl-function-type ::= type* generic-signature 'I' FUNC-ATTRIBUTES '_'

FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? PARAM-CONVENTION* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)?
FUNC-ATTRIBUTES ::= PATTERN-SUBS? INVOCATION-SUBS? PSEUDO-GENERIC? CALLEE-ESCAPE? DIFFERENTIABILITY-KIND? CALLEE-CONVENTION FUNC-REPRESENTATION? COROUTINE-KIND? PARAM-CONVENTION* RESULT-CONVENTION* ('Y' PARAM-CONVENTION)* ('z' RESULT-CONVENTION)?

PATTERN-SUBS ::= 's' // has pattern substitutions
INVOCATION-SUB ::= 'I' // has invocation substitutions
PSEUDO-GENERIC ::= 'P'

CALLEE-ESCAPE ::= 'e' // @escaping (inverse of SIL @noescape)

DIFFERENTIABILITY-KIND ::= DIFFERENTIABLE | LINEAR
DIFFERENTIABLE ::= 'd' // @differentiable
LINEAR ::= 'l' // @differentiable(linear)

CALLEE-CONVENTION ::= 'y' // @callee_unowned
CALLEE-CONVENTION ::= 'g' // @callee_guaranteed
CALLEE-CONVENTION ::= 'x' // @callee_owned
Expand Down
11 changes: 11 additions & 0 deletions docs/DebuggingTheCompiler.rst
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,17 @@ we know to ignore swift_getGenericMetadata 84 times, i.e.::

(lldb) br set -i 84 -n GlobalARCOpts::run

A final trick is that one can use the -R option to stop at a relative assembly
address in lldb. Specifically, lldb resolves the breakpoint normally and then
just adds the argument -R to the address. So for instance, if I want to stop at
the address at +38 in the function with the name 'foo', I would write::

(lldb) br set -R 38 -n foo

Then lldb would add 38 to the offset of foo and break there. This is really
useful in contexts where one wants to set a breakpoint at an assembly address
that is stable across multiple different invocations of lldb.

LLDB Scripts
~~~~~~~~~~~~

Expand Down
35 changes: 23 additions & 12 deletions docs/Diagnostics.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,23 +92,34 @@ Most diagnostics have no reason to change behavior under editor mode. An example

### Educational Notes ###

**Note**: This feature is currently experimental. It can be enabled by passing the `-Xfrontend -enable-descriptive-diagnostics` flag.
Educational notes are short-form documentation attached to a diagnostic which explain relevant language concepts. They are intended to further Swift's goal of progressive disclosure by providing a learning resource at the point of use when encountering an error message for the first time. In very limited circumstances, they also allow the main diagnostic message to use precise terminology (e.g. nominal types) which would otherwise be too unfriendly for beginners.

Educational notes are small snippets of documentation attached to a diagnostic which explain relevant language concepts. They are intended to further Swift's goal of progressive disclosure by providing a learning resource at the point of use for users encountering a new error message for the first time. In very limited circumstances, they also allow the main diagnostic message to use more precise and correct terminology (e.g. nominal types) which would otherwise be too unfriendly for beginners.
When outputting diagnostics on the command line, educational notes will be printed after the main diagnostic body if enabled using the `-print-educational-notes` driver option. When presented in an IDE, it's expected they will be collapsed under a disclosure arrow, info button, or similar to avoid cluttering output.

When outputting diagnostics on the command line, educational notes will be printed after the main diagnostic body if descriptive diagnostics are enabled. When presented in an IDE, it's expected they will be collapsed under a disclosure arrow, info button, or similar to avoid cluttering output.

Generally speaking, a diagnostic should try to provide educational notes for any concepts/terminology which is difficult to understand from context or is especially subtle. Educational notes should:
- Explain a single language concept. This makes them easy to reuse across diagnostics and helps keep them clear, concise, and easy to understand.
- Be written in unabbreviated English. These are longer form messages compared to the main diagnostic, so there is no need to omit needless words and punctuation.
- Not generally exceed 3-4 paragraphs. Educational notes should be clear and easily digestible. Messages which are too long also have the potential to create diagnostics UX issues in some contexts.
Educational notes should:
- Explain a single language concept. This makes them easy to reuse across related diagnostics and helps keep them clear, concise, and easy to understand.
- Be written in unabbreviated English. These are longer-form messages compared to the main diagnostic, so there's no need to omit needless words and punctuation.
- Not generally exceed 3-4 paragraphs. Educational notes should be clear and easily digestible. Messages which are too long also have the potential to create UX issues on the command line.
- Be accessible. Educational notes should be beginner friendly and avoid assuming unnecesary prior knowledge. The goal is not only to help users understand what a diagnostic is telling them, but also to turn errors and warnings into "teachable moments".
- Include references to relevant chapters of _The Swift Programming Language_ if applicable.
- Be written in Markdown, but avoid excessive markup to avoid impacting the terminal UX.
- Include references to relevant chapters of _The Swift Programming Language_.
- Be written in Markdown, but avoid excessive markup which negatively impacts the terminal UX.

### Quick-Start Guide for Contributing New Educational Notes ###

Adding new educational notes is a great way to get familiar with the process of contributing to Swift, while also making a big impact!

To add a new educational note:
1. Add a new Markdown file in the `userdocs/diagnostics/` directory containing the contents of the note.
2. Associate the note with one or more diagnostics in EducationalNotes.def.
1. Follow the [directions in the README](https://github.com/apple/swift#getting-sources-for-swift-and-related-projects) to checkout the Swift sources locally. Being able to build the Swift compiler is recommended, but not required, when contributing a new note.
2. Identify a diagnostic to write an educational note for. To associate an educational note with a diagnostic name, you'll need to know its internal identifier. The easiest way to do this is to write a small program which triggers the diagnostic, and run it using the `-debug-diagnostic-names` compiler flag. This flag will cause the internal diagnostic identifier to be printed after the diagnostic message in square brackets.
3. Find any closely related diagnostics. Sometimes, what appears to be one diagnostic from a user's perspective may have multiple variations internally. After determining a diagnostic's internal identifier, run a search for it in the compiler source. You should find:
- An entry in a `Diagnostics*.def` file describing the diagnostic. If there are any closely related diagnostics the note should also be attached to, they can usually be found nearby.
- Each point in the compiler source where the diagnostic is emitted. This can be helpful in determining the exact circumstances which cause it to be emitted.
4. Add a new Markdown file in the `userdocs/diagnostics/` directory in the swift repository containing the contents of the note. When writing a note, keep the writing guidelines from the section above in mind. The existing notes in the directory are another useful guide.
5. Associate the note with the appropriate diagnostics in `EducationalNotes.def`. An entry like `EDUCATIONAL_NOTES(property_wrapper_failable_init, "property-wrapper-requirements.md")` will associate the note with filename `property-wrapper-requirements.md` with the diagnostic having an internal identifier of `property_wrapper_failable_init`.
6. If possible, rebuild the compiler and try recompiling your test program with `-print-educational-notes`. Your new note should appear after the diagnostic in the terminal.
7. That's it! The new note is now ready to be submitted as a pull request on GitHub.

If you run into any issues or have questions while following the steps above, feel free to post a question on the Swift forums or open a work-in-progress pull request on GitHub.

### Format Specifiers ###

Expand Down
41 changes: 38 additions & 3 deletions include/swift/ABI/MetadataValues.h
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,14 @@ enum class FunctionMetadataConvention: uint8_t {
CFunctionPointer = 3,
};

/// Differentiability kind for function type metadata.
/// Duplicates `DifferentiabilityKind` in AutoDiff.h.
enum class FunctionMetadataDifferentiabilityKind: uint8_t {
NonDifferentiable = 0b00,
Normal = 0b01,
Linear = 0b11
};

/// Flags in a function type metadata record.
template <typename int_type>
class TargetFunctionTypeFlags {
Expand All @@ -777,6 +785,8 @@ class TargetFunctionTypeFlags {
ThrowsMask = 0x01000000U,
ParamFlagsMask = 0x02000000U,
EscapingMask = 0x04000000U,
DifferentiableMask = 0x08000000U,
LinearMask = 0x10000000U
};
int_type Data;

Expand All @@ -801,6 +811,16 @@ class TargetFunctionTypeFlags {
(throws ? ThrowsMask : 0));
}

constexpr TargetFunctionTypeFlags<int_type> withDifferentiabilityKind(
FunctionMetadataDifferentiabilityKind differentiability) const {
return TargetFunctionTypeFlags<int_type>(
(Data & ~DifferentiableMask & ~LinearMask) |
(differentiability == FunctionMetadataDifferentiabilityKind::Normal
? DifferentiableMask : 0) |
(differentiability == FunctionMetadataDifferentiabilityKind::Linear
? LinearMask : 0));
}

constexpr TargetFunctionTypeFlags<int_type>
withParameterFlags(bool hasFlags) const {
return TargetFunctionTypeFlags<int_type>((Data & ~ParamFlagsMask) |
Expand Down Expand Up @@ -829,6 +849,19 @@ class TargetFunctionTypeFlags {

bool hasParameterFlags() const { return bool(Data & ParamFlagsMask); }

bool isDifferentiable() const {
return getDifferentiabilityKind() >=
FunctionMetadataDifferentiabilityKind::Normal;
}

FunctionMetadataDifferentiabilityKind getDifferentiabilityKind() const {
if (bool(Data & DifferentiableMask))
return FunctionMetadataDifferentiabilityKind::Normal;
if (bool(Data & LinearMask))
return FunctionMetadataDifferentiabilityKind::Linear;
return FunctionMetadataDifferentiabilityKind::NonDifferentiable;
}

int_type getIntValue() const {
return Data;
}
Expand All @@ -849,9 +882,10 @@ using FunctionTypeFlags = TargetFunctionTypeFlags<size_t>;
template <typename int_type>
class TargetParameterTypeFlags {
enum : int_type {
ValueOwnershipMask = 0x7F,
VariadicMask = 0x80,
AutoClosureMask = 0x100,
ValueOwnershipMask = 0x7F,
VariadicMask = 0x80,
AutoClosureMask = 0x100,
NoDerivativeMask = 0x200
};
int_type Data;

Expand Down Expand Up @@ -881,6 +915,7 @@ class TargetParameterTypeFlags {
bool isNone() const { return Data == 0; }
bool isVariadic() const { return Data & VariadicMask; }
bool isAutoClosure() const { return Data & AutoClosureMask; }
bool isNoDerivative() const { return Data & NoDerivativeMask; }

ValueOwnership getValueOwnership() const {
return (ValueOwnership)(Data & ValueOwnershipMask);
Expand Down
13 changes: 13 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,19 @@ class ASTContext final {
unsigned previousGeneration,
llvm::TinyPtrVector<AbstractFunctionDecl *> &methods);

/// Load derivative function configurations for the given
/// AbstractFunctionDecl.
///
/// \param originalAFD The declaration whose derivative function
/// configurations should be loaded.
///
/// \param previousGeneration The previous generation number. The AST already
/// contains derivative function configurations loaded from any generation up
/// to and including this one.
void loadDerivativeFunctionConfigurations(
AbstractFunctionDecl *originalAFD, unsigned previousGeneration,
llvm::SetVector<AutoDiffConfig> &results);

/// Retrieve the Clang module loader for this ASTContext.
///
/// If there is no Clang module loader, returns a null pointer.
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/ASTTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ SWIFT_TYPEID_NAMED(Optional<PropertyWrapperMutability>,
PropertyWrapperMutability)
SWIFT_TYPEID_NAMED(ParamDecl *, ParamDecl)
SWIFT_TYPEID_NAMED(PatternBindingEntry *, PatternBindingEntry)
SWIFT_TYPEID_NAMED(PostfixOperatorDecl *, PostfixOperatorDecl)
SWIFT_TYPEID_NAMED(PrecedenceGroupDecl *, PrecedenceGroupDecl)
SWIFT_TYPEID_NAMED(PrefixOperatorDecl *, PrefixOperatorDecl)
SWIFT_TYPEID_NAMED(ProtocolDecl *, ProtocolDecl)
SWIFT_TYPEID_NAMED(SourceFile *, SourceFile)
SWIFT_TYPEID_NAMED(TypeAliasDecl *, TypeAliasDecl)
Expand Down
2 changes: 2 additions & 0 deletions include/swift/AST/ASTTypeIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ class OpaqueTypeDecl;
class PatternBindingEntry;
class ParamDecl;
enum class ParamSpecifier : uint8_t;
class PostfixOperatorDecl;
class PrecedenceGroupDecl;
class PrefixOperatorDecl;
struct PropertyWrapperBackingPropertyInfo;
struct PropertyWrapperTypeInfo;
enum class CtorInitializerKind;
Expand Down
9 changes: 3 additions & 6 deletions include/swift/AST/AccessRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,7 @@ class AccessLevelRequest :
friend SimpleRequest;

// Evaluation.
llvm::Expected<AccessLevel> evaluate(Evaluator &evaluator,
ValueDecl *decl) const;
AccessLevel evaluate(Evaluator &evaluator, ValueDecl *decl) const;

public:
// Separate caching.
Expand All @@ -65,8 +64,7 @@ class SetterAccessLevelRequest :
friend SimpleRequest;

// Evaluation.
llvm::Expected<AccessLevel>
evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;
AccessLevel evaluate(Evaluator &evaluator, AbstractStorageDecl *decl) const;

public:
// Separate caching.
Expand All @@ -88,8 +86,7 @@ class DefaultAndMaxAccessLevelRequest :
friend SimpleRequest;

// Evaluation.
llvm::Expected<DefaultAndMax>
evaluate(Evaluator &evaluator, ExtensionDecl *decl) const;
DefaultAndMax evaluate(Evaluator &evaluator, ExtensionDecl *decl) const;

public:
// Separate caching.
Expand Down
5 changes: 5 additions & 0 deletions include/swift/AST/Attr.def
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,11 @@ DECL_ATTR(transpose, Transpose,
ABIStableToAdd | ABIBreakingToRemove | APIStableToAdd | APIBreakingToRemove,
99)

SIMPLE_DECL_ATTR(noDerivative, NoDerivative,
OnAbstractFunction | OnVar | OnSubscript |
ABIBreakingToAdd | ABIBreakingToRemove | APIBreakingToAdd | APIBreakingToRemove,
100)

#undef TYPE_ATTR
#undef DECL_ATTR_ALIAS
#undef CONTEXTUAL_DECL_ATTR_ALIAS
Expand Down
48 changes: 28 additions & 20 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2186,6 +2186,9 @@ class PatternBindingDecl final : public Decl,
/// Can the pattern at index i be default initialized?
bool isDefaultInitializable(unsigned i) const;

/// Can the property wrapper be used to provide default initialization?
bool isDefaultInitializableViaPropertyWrapper(unsigned i) const;

/// Does this pattern have a user-provided initializer expression?
bool isExplicitlyInitialized(unsigned i) const;

Expand Down Expand Up @@ -2433,6 +2436,7 @@ class ValueDecl : public Decl {
friend class IsDynamicRequest;
friend class IsImplicitlyUnwrappedOptionalRequest;
friend class InterfaceTypeRequest;
friend class CheckRedeclarationRequest;
friend class Decl;
SourceLoc getLocFromSource() const { return NameLoc; }
protected:
Expand All @@ -2454,24 +2458,24 @@ class ValueDecl : public Decl {
Bits.ValueDecl.AlreadyInLookupTable = value;
}

public:
/// Return true if this protocol member is a protocol requirement.
///
/// Asserts if this is not a member of a protocol.
bool isProtocolRequirement() const;

/// Determine whether we have already checked whether this
/// declaration is a redeclaration.
bool alreadyCheckedRedeclaration() const {
bool alreadyCheckedRedeclaration() const {
return Bits.ValueDecl.CheckedRedeclaration;
}

/// Set whether we have already checked this declaration as a
/// redeclaration.
void setCheckedRedeclaration(bool checked) {
Bits.ValueDecl.CheckedRedeclaration = checked;
void setCheckedRedeclaration() {
Bits.ValueDecl.CheckedRedeclaration = true;
}

public:
/// Return true if this protocol member is a protocol requirement.
///
/// Asserts if this is not a member of a protocol.
bool isProtocolRequirement() const;

void setUserAccessible(bool Accessible) {
Bits.ValueDecl.IsUserAccessible = Accessible;
}
Expand Down Expand Up @@ -5138,15 +5142,17 @@ class VarDecl : public AbstractStorageDecl {
void setTopLevelGlobal(bool b) { Bits.VarDecl.IsTopLevelGlobal = b; }

/// Retrieve the custom attributes that attach property wrappers to this
/// property. The returned list contains all of the attached property wrapper attributes in source order,
/// which means the outermost wrapper attribute is provided first.
/// property. The returned list contains all of the attached property wrapper
/// attributes in source order, which means the outermost wrapper attribute
/// is provided first.
llvm::TinyPtrVector<CustomAttr *> getAttachedPropertyWrappers() const;

/// Whether this property has any attached property wrappers.
bool hasAttachedPropertyWrapper() const;

/// Whether all of the attached property wrappers have an init(initialValue:) initializer.
bool allAttachedPropertyWrappersHaveInitialValueInit() const;
/// Whether all of the attached property wrappers have an init(wrappedValue:)
/// initializer.
bool allAttachedPropertyWrappersHaveWrappedValueInit() const;

/// Retrieve the type of the attached property wrapper as a contextual
/// type.
Expand Down Expand Up @@ -5210,7 +5216,7 @@ class VarDecl : public AbstractStorageDecl {
/// \end
///
/// Or when there is no initializer but each composed property wrapper has
/// a suitable `init(initialValue:)`.
/// a suitable `init(wrappedValue:)`.
bool isPropertyMemberwiseInitializedWithWrappedType() const;

/// Whether the innermost property wrapper's initializer's 'wrappedValue' parameter
Expand Down Expand Up @@ -5796,6 +5802,7 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
private:
ParameterList *Params;

private:
/// The generation at which we last loaded derivative function configurations.
unsigned DerivativeFunctionConfigGeneration = 0;
/// Prepare to traverse the list of derivative function configurations.
Expand All @@ -5810,6 +5817,13 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
struct DerivativeFunctionConfigurationList;
DerivativeFunctionConfigurationList *DerivativeFunctionConfigs = nullptr;

public:
/// Get all derivative function configurations.
ArrayRef<AutoDiffConfig> getDerivativeFunctionConfigurations();

/// Add the given derivative function configuration.
void addDerivativeFunctionConfiguration(AutoDiffConfig config);

protected:
// If a function has a body at all, we have either a parsed body AST node or
// we have saved the end location of the unparsed body.
Expand Down Expand Up @@ -6129,12 +6143,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
/// constructor.
bool hasDynamicSelfResult() const;

/// Get all derivative function configurations.
ArrayRef<AutoDiffConfig> getDerivativeFunctionConfigurations();

/// Add the given derivative function configuration.
void addDerivativeFunctionConfiguration(AutoDiffConfig config);

using DeclContext::operator new;
using Decl::getASTContext;
};
Expand Down
Loading

0 comments on commit 1b79306

Please sign in to comment.