Skip to content

[5.9] Omnibus merge of some recent variadic generics work #64683

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 30 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
e072ad2
[NFC] Change the printing of AbstractionPattern to include the sub map
rjmccall Mar 22, 2023
3b10e59
Fix unsafeGetSubstFieldType to propagate a substitution map in
rjmccall Mar 22, 2023
75782df
When we are performing SIL substitution, and we reach a type that
rjmccall Mar 22, 2023
9fd961a
When computing the field type of a SILType, add substitutions to the …
rjmccall Mar 22, 2023
a1b49bd
Do proper parallel walks of orig+subst types when computing type
rjmccall Mar 22, 2023
d648cf1
Do a proper orig+subst walk of tuple expression elements in call
rjmccall Mar 22, 2023
1f43cf2
[NFC] Rename isPackExpansion -> isOrigPackExpansion for clarity
rjmccall Mar 22, 2023
98b60e3
Add a test case for the work in this PR.
rjmccall Mar 22, 2023
b82c81c
[NFC] Move forEachTupleElement to use a generator
rjmccall Mar 22, 2023
eaec511
[NFC] Rename Generator::getCurrent() to Generator::get()
rjmccall Mar 23, 2023
239bcd8
Fix memberwise initializers for structs with variadic-tuple fields
rjmccall Mar 23, 2023
dd9ae1d
[NFC] Thread a common type through all the AST substitution code.
rjmccall Mar 23, 2023
9c9b153
[NFC] Split the SIL type substitution code into its own file
rjmccall Mar 23, 2023
cbbdc83
[NFC] Add a convenience function to IFS
rjmccall Mar 23, 2023
aa713a8
[NFC] Add an operation to change the current options on NFC
rjmccall Mar 23, 2023
ad091a4
[NFC] Use InFlightSubstitution in the SIL type substituter
rjmccall Mar 23, 2023
6cb5dbc
The canonical type of a pack expansion has a reduced shape.
rjmccall Mar 25, 2023
532000f
Perform component-wise substitution of pack expansions immediately.
rjmccall Mar 25, 2023
5229198
Remove some dead code; these operations are now done directly in
rjmccall Mar 25, 2023
9f74a11
Fix the dumping of AbstractionPatterns with substitutions
rjmccall Mar 27, 2023
af752fb
Pass down the substitutions of the original pattern when extracting
rjmccall Mar 27, 2023
cf94aa7
Assert that we don't produce a SILFunction with a type with opened
rjmccall Mar 27, 2023
070cfb0
Make BlackHoleInitialization support pack initialization
rjmccall Mar 27, 2023
a4edc3e
Teach ResultPlan to handle packs correctly when we're not emitting
rjmccall Mar 28, 2023
6badca6
[PackExpansionMatcher] Adjust ParamPackMatcher to account for labels
xedin Mar 23, 2023
c9b8140
[CSSimplify] NFC: Refactor `TupleMatcher` to consolidate pack expansi…
xedin Mar 23, 2023
eb475b4
[AST] NFC: Unify implementation for pack expansion matching for type …
xedin Mar 23, 2023
659f5df
[AST] PackExpansionMatcher: use common prefix/suffix algorithm for tu…
xedin Mar 23, 2023
9d24f80
[AST] PackExpansionMatcher/NFC: Templatarize `TypeListPackMatcher`
xedin Mar 24, 2023
92afbc5
[AST] PackExpansionMatcher/NFC: Rename `{lhs, rhs}Params` to `{lhs, r…
xedin Mar 24, 2023
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
179 changes: 179 additions & 0 deletions include/swift/AST/InFlightSubstitution.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
//===--- InFlightSubstitution.h - In-flight substitution data ---*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
// This file defines the InFlightSubstitution structure, which captures
// all the information about a type substitution that's currently in
// progress. For now, this is meant to be an internal implementation
// detail of the substitution system, and other systems should not use
// it (unless they are part of the extended substitution system, such as
// the SIL type substituter)
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_AST_INFLIGHTSUBSTITUTION_H
#define SWIFT_AST_INFLIGHTSUBSTITUTION_H

#include "swift/AST/SubstitutionMap.h"

namespace swift {
class SubstitutionMap;

class InFlightSubstitution {
SubstOptions Options;
TypeSubstitutionFn BaselineSubstType;
LookupConformanceFn BaselineLookupConformance;

struct ActivePackExpansion {
bool isSubstExpansion = false;
unsigned expansionIndex = 0;
};
SmallVector<ActivePackExpansion, 4> ActivePackExpansions;

public:
InFlightSubstitution(TypeSubstitutionFn substType,
LookupConformanceFn lookupConformance,
SubstOptions options)
: Options(options),
BaselineSubstType(substType),
BaselineLookupConformance(lookupConformance) {}

InFlightSubstitution(const InFlightSubstitution &) = delete;
InFlightSubstitution &operator=(const InFlightSubstitution &) = delete;

// TODO: when we add PackElementType, we should recognize it during
// substitution and either call different methods on this class or
// pass an extra argument for the pack-expansion depth D. We should
// be able to rely on that to mark a pack-element reference instead
// of checking whether the original type was a pack. Substitution
// should use the D'th entry from the end of ActivePackExpansions to
// guide the element substitution:
// - project the given index of the pack substitution
// - wrap it in a PackElementType if it's a subst expansion
// - the depth of that PackElementType is the number of subst
// expansions between the depth entry and the end of
// ActivePackExpansions

/// Perform primitive substitution on the given type. Returns Type()
/// if the type should not be substituted as a whole.
Type substType(SubstitutableType *origType);

/// Perform primitive conformance lookup on the given type.
ProtocolConformanceRef lookupConformance(CanType dependentType,
Type conformingReplacementType,
ProtocolDecl *conformedProtocol);

/// Given the shape type of a pack expansion, invoke the given callback
/// for each expanded component of it. If the substituted component
/// is an expansion component, the desired shape of that expansion
/// is passed as the argument; otherwise, the argument is Type().
/// In either case, an active expansion is entered on this IFS for
/// the duration of the call to handleComponent, and subsequent
/// pack-element type references will substitute to the corresponding
/// element of the substitution of the pack.
void expandPackExpansionShape(Type origShape,
llvm::function_ref<void(Type substComponentShape)> handleComponent);

/// Call the given function for each expanded component type of the
/// given pack expansion type. The function will be invoked with the
/// active expansion still active.
void expandPackExpansionType(PackExpansionType *origExpansionType,
llvm::function_ref<void(Type substType)> handleComponentType) {
expandPackExpansionShape(origExpansionType->getCountType(),
[&](Type substComponentShape) {
auto origPatternType = origExpansionType->getPatternType();
auto substEltType = origPatternType.subst(*this);

auto substComponentType =
(substComponentShape
? PackExpansionType::get(substEltType, substComponentShape)
: substEltType);
handleComponentType(substComponentType);
});
}

/// Return a list of component types that the pack expansion expands to.
SmallVector<Type, 8>
expandPackExpansionType(PackExpansionType *origExpansionType) {
SmallVector<Type, 8> substComponentTypes;
expandPackExpansionType(origExpansionType, substComponentTypes);
return substComponentTypes;
}

/// Expand the list of component types that the pack expansion expands
/// to into the given array.
void expandPackExpansionType(PackExpansionType *origExpansionType,
SmallVectorImpl<Type> &substComponentTypes) {
expandPackExpansionType(origExpansionType, [&](Type substComponentType) {
substComponentTypes.push_back(substComponentType);
});
}

class OptionsAdjustmentScope {
InFlightSubstitution &IFS;
SubstOptions SavedOptions;

public:
OptionsAdjustmentScope(InFlightSubstitution &IFS, SubstOptions newOptions)
: IFS(IFS), SavedOptions(IFS.Options) {
IFS.Options = newOptions;
}

OptionsAdjustmentScope(const OptionsAdjustmentScope &) = delete;
OptionsAdjustmentScope &operator=(const OptionsAdjustmentScope &) = delete;

~OptionsAdjustmentScope() {
IFS.Options = SavedOptions;
}
};

template <class Fn>
auto withNewOptions(SubstOptions options, Fn &&fn)
-> decltype(std::forward<Fn>(fn)()) {
OptionsAdjustmentScope scope(*this, options);
return std::forward<Fn>(fn)();
}

SubstOptions getOptions() const {
return Options;
}

bool shouldSubstituteOpaqueArchetypes() const {
return Options.contains(SubstFlags::SubstituteOpaqueArchetypes);
}

/// Is the given type invariant to substitution?
bool isInvariant(Type type) const;
};

/// A helper classes that provides stable storage for the query
/// functions against a SubstitutionMap.
struct InFlightSubstitutionViaSubMapHelper {
QuerySubstitutionMap QueryType;
LookUpConformanceInSubstitutionMap QueryConformance;

InFlightSubstitutionViaSubMapHelper(SubstitutionMap subMap)
: QueryType{subMap}, QueryConformance(subMap) {}
};
class InFlightSubstitutionViaSubMap :
private InFlightSubstitutionViaSubMapHelper,
public InFlightSubstitution {

public:
InFlightSubstitutionViaSubMap(SubstitutionMap subMap,
SubstOptions options)
: InFlightSubstitutionViaSubMapHelper(subMap),
InFlightSubstitution(QueryType, QueryConformance, options) {}
};

} // end namespace swift

#endif
7 changes: 7 additions & 0 deletions include/swift/AST/PackConformance.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,13 @@ class alignas(1 << DeclAlignInBits) PackConformance final
LookupConformanceFn conformances,
SubstOptions options=None) const;

/// Apply an in-flight substitution to the conformances in this
/// protocol conformance ref.
///
/// This function should generally not be used outside of the
/// substitution subsystem.
ProtocolConformanceRef subst(InFlightSubstitution &IFS) const;

SWIFT_DEBUG_DUMP;
void dump(llvm::raw_ostream &out, unsigned indent = 0) const;
};
Expand Down
Loading