Skip to content

Commit 7f22faf

Browse files
committed
Substantially rework how SILGen handles bridging as part of laying the
ground work for the syntactic bridging peephole. - Pass source and dest formal types to the bridging routines in addition to the dest lowered type. The dest lowered type is still necessary in order to handle non-standard abstraction patterns for the dest type. - Change bridging abstraction patterns to store bridged formal types instead of the formal type. - Improve how SIL type lowering deals with import-as-member patterns. - Fix some AST bugs where inadequate information was being stored in various expressions. - Introduce the idea of a converting SGFContext and use it to regularize the existing id-as-Any conversion peephole. - Improve various places in SILGen to emit directly into contexts.
1 parent 8bf2b37 commit 7f22faf

36 files changed

+2918
-1354
lines changed

include/swift/AST/Expr.h

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -342,9 +342,9 @@ class alignas(8) Expr {
342342
class TupleShuffleExprBitfields {
343343
friend class TupleShuffleExpr;
344344
unsigned : NumImplicitConversionExprBits;
345-
unsigned IsSourceScalar : 1;
345+
unsigned TypeImpact : 2;
346346
};
347-
enum { NumTupleShuffleExprBits = NumImplicitConversionExprBits + 1 };
347+
enum { NumTupleShuffleExprBits = NumImplicitConversionExprBits + 2 };
348348
static_assert(NumTupleShuffleExprBits <= 32, "fits in an unsigned");
349349

350350
class ApplyExprBitfields {
@@ -2804,7 +2804,7 @@ class UnevaluatedInstanceExpr : public ImplicitConversionExpr {
28042804
};
28052805

28062806
/// TupleShuffleExpr - This represents a permutation of a tuple value to a new
2807-
/// tuple type. The expression's type is known to be a tuple type.
2807+
/// tuple type.
28082808
///
28092809
/// If hasScalarSource() is true, the subexpression should be treated
28102810
/// as if it were implicitly injected into a single-element tuple
@@ -2825,9 +2825,22 @@ class TupleShuffleExpr : public ImplicitConversionExpr {
28252825
CallerDefaultInitialize = -3
28262826
};
28272827

2828-
enum SourceIsScalar_t : bool {
2829-
SourceIsTuple = false,
2830-
SourceIsScalar = true
2828+
enum TypeImpact {
2829+
/// The source value is a tuple which is destructured and modified to
2830+
/// create the result, which is a tuple.
2831+
TupleToTuple,
2832+
2833+
/// The source value is a tuple which is destructured and modified to
2834+
/// create the result, which is a scalar because it has one element and
2835+
/// no labels.
2836+
TupleToScalar,
2837+
2838+
/// The source value is an individual value (possibly one with tuple
2839+
/// type) which is inserted into a particular position in the result,
2840+
/// which is a tuple.
2841+
ScalarToTuple
2842+
2843+
// (TupleShuffleExprs are never created for a scalar-to-scalar conversion.)
28312844
};
28322845

28332846
private:
@@ -2851,7 +2864,7 @@ class TupleShuffleExpr : public ImplicitConversionExpr {
28512864

28522865
public:
28532866
TupleShuffleExpr(Expr *subExpr, ArrayRef<int> elementMapping,
2854-
SourceIsScalar_t isSourceScalar,
2867+
TypeImpact typeImpact,
28552868
ConcreteDeclRef defaultArgsOwner,
28562869
ArrayRef<unsigned> VariadicArgs,
28572870
Type VarargsArrayTy,
@@ -2862,17 +2875,23 @@ class TupleShuffleExpr : public ImplicitConversionExpr {
28622875
DefaultArgsOwner(defaultArgsOwner), VariadicArgs(VariadicArgs),
28632876
CallerDefaultArgs(CallerDefaultArgs)
28642877
{
2865-
TupleShuffleExprBits.IsSourceScalar = isSourceScalar;
2878+
TupleShuffleExprBits.TypeImpact = typeImpact;
28662879
}
28672880

28682881
ArrayRef<int> getElementMapping() const { return ElementMapping; }
28692882

2870-
/// Is the source expression scalar?
2871-
///
2872-
/// This doesn't necessarily mean it's not a tuple; it just means
2873-
/// that it should be treated as if it were an element of a
2874-
/// single-element tuple for the purposes of interpreting behavior.
2875-
bool isSourceScalar() const { return TupleShuffleExprBits.IsSourceScalar; }
2883+
/// What is the type impact of this shuffle?
2884+
TypeImpact getTypeImpact() const {
2885+
return TypeImpact(TupleShuffleExprBits.TypeImpact);
2886+
}
2887+
2888+
bool isSourceScalar() const {
2889+
return getTypeImpact() == ScalarToTuple;
2890+
}
2891+
2892+
bool isResultScalar() const {
2893+
return getTypeImpact() == TupleToScalar;
2894+
}
28762895

28772896
Type getVarargsArrayType() const {
28782897
assert(!VarargsArrayTy.isNull());

include/swift/AST/ForeignInfo.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===--- ForeignInfo.h - Declaration import information ---------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines the ForeignInfo structure, which includes
14+
// structural information about how a foreign API's physical type
15+
// maps into the Swift type system.
16+
//
17+
//===----------------------------------------------------------------------===//
18+
19+
#ifndef SWIFT_FOREIGN_INFO_H
20+
#define SWIFT_FOREIGN_INFO_H
21+
22+
#include "swift/AST/ForeignErrorConvention.h"
23+
#include "swift/AST/Decl.h"
24+
25+
namespace swift {
26+
27+
struct ForeignInfo {
28+
ImportAsMemberStatus Self;
29+
Optional<ForeignErrorConvention> Error;
30+
};
31+
32+
} // end namespace swift
33+
34+
#endif

include/swift/AST/Types.h

Lines changed: 88 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2356,6 +2356,17 @@ class AnyFunctionType : public TypeBase {
23562356
/// Whether the parameter is marked 'inout'
23572357
bool isInOut() const { return Flags.isInOut(); }
23582358
};
2359+
2360+
class CanParam : public Param {
2361+
explicit CanParam(const Param &param) : Param(param) {}
2362+
public:
2363+
static CanParam getFromParam(const Param &param) { return CanParam(param); }
2364+
2365+
CanType getType() const { return CanType(Param::getType()); }
2366+
};
2367+
2368+
using CanParamArrayRef =
2369+
ArrayRefView<Param,CanParam,CanParam::getFromParam,/*AccessOriginal*/true>;
23592370

23602371
/// \brief A class which abstracts out some details necessary for
23612372
/// making a call.
@@ -2515,11 +2526,17 @@ class AnyFunctionType : public TypeBase {
25152526
/// needed.
25162527
static Type composeInput(ASTContext &ctx, ArrayRef<Param> params,
25172528
bool canonicalVararg);
2529+
static Type composeInput(ASTContext &ctx, CanParamArrayRef params,
2530+
bool canonicalVararg) {
2531+
return composeInput(ctx, params.getOriginalArray(), canonicalVararg);
2532+
}
25182533

25192534
Type getInput() const { return Input; }
25202535
Type getResult() const { return Output; }
25212536
ArrayRef<AnyFunctionType::Param> getParams() const;
25222537
unsigned getNumParams() const { return NumParams; }
2538+
2539+
GenericSignature *getOptGenericSignature() const;
25232540

25242541
ExtInfo getExtInfo() const {
25252542
return ExtInfo(AnyFunctionTypeBits.ExtInfo);
@@ -2561,14 +2578,26 @@ class AnyFunctionType : public TypeBase {
25612578
}
25622579
};
25632580
BEGIN_CAN_TYPE_WRAPPER(AnyFunctionType, Type)
2564-
typedef AnyFunctionType::ExtInfo ExtInfo;
2581+
using ExtInfo = AnyFunctionType::ExtInfo;
2582+
using CanParamArrayRef = AnyFunctionType::CanParamArrayRef;
2583+
2584+
static CanAnyFunctionType get(CanGenericSignature signature,
2585+
CanType input, CanType result);
2586+
static CanAnyFunctionType get(CanGenericSignature signature,
2587+
CanType input, CanType result,
2588+
const ExtInfo &extInfo);
2589+
static CanAnyFunctionType get(CanGenericSignature signature,
2590+
CanParamArrayRef params,
2591+
CanType result, const ExtInfo &info);
2592+
2593+
CanGenericSignature getOptGenericSignature() const;
25652594

25662595
CanType getInput() const {
25672596
return getPointer()->getInput()->getCanonicalType();
25682597
}
2569-
2570-
ArrayRef<AnyFunctionType::Param> getParams() const {
2571-
return getPointer()->getParams();
2598+
2599+
CanParamArrayRef getParams() const {
2600+
return CanParamArrayRef(getPointer()->getParams());
25722601
}
25732602

25742603
PROXY_CAN_TYPE_SIMPLE_GETTER(getResult)
@@ -2616,20 +2645,19 @@ class FunctionType final : public AnyFunctionType,
26162645
};
26172646
BEGIN_CAN_TYPE_WRAPPER(FunctionType, AnyFunctionType)
26182647
static CanFunctionType get(CanType input, CanType result) {
2619-
return CanFunctionType(
2620-
FunctionType::get(input, result)
2621-
->getCanonicalType()->castTo<FunctionType>());
2648+
auto fnType = FunctionType::get(input, result);
2649+
return cast<FunctionType>(fnType->getCanonicalType());
26222650
}
26232651
static CanFunctionType get(CanType input, CanType result,
26242652
const ExtInfo &info) {
2625-
return CanFunctionType(
2626-
FunctionType::get(input, result, info)
2627-
->getCanonicalType()->castTo<FunctionType>());
2653+
auto fnType = FunctionType::get(input, result, info);
2654+
return cast<FunctionType>(fnType->getCanonicalType());
26282655
}
2629-
static CanFunctionType get(ArrayRef<AnyFunctionType::Param> params,
2630-
Type result, const ExtInfo &info) {
2631-
return CanFunctionType(FunctionType::get(params, result, info,
2632-
/*canonicalVararg=*/true));
2656+
static CanFunctionType get(CanParamArrayRef params, CanType result,
2657+
const ExtInfo &info) {
2658+
auto fnType = FunctionType::get(params.getOriginalArray(),
2659+
result, info, /*canonicalVararg=*/true);
2660+
return cast<FunctionType>(fnType->getCanonicalType());
26332661
}
26342662

26352663
CanFunctionType withExtInfo(ExtInfo info) const {
@@ -2749,13 +2777,13 @@ BEGIN_CAN_TYPE_WRAPPER(GenericFunctionType, AnyFunctionType)
27492777

27502778
/// Create a new generic function type.
27512779
static CanGenericFunctionType get(CanGenericSignature sig,
2752-
ArrayRef<AnyFunctionType::Param> params,
2753-
CanType result,
2780+
CanParamArrayRef params, CanType result,
27542781
const ExtInfo &info) {
27552782
// Knowing that the argument types are independently canonical is
27562783
// not sufficient to guarantee that the function type will be canonical.
2757-
auto fnType = GenericFunctionType::get(sig, params, result, info,
2758-
/*canonicalVararg=*/true);
2784+
auto fnType = GenericFunctionType::get(sig, params.getOriginalArray(),
2785+
result, info,
2786+
/*canonicalVararg=*/true);
27592787
return cast<GenericFunctionType>(fnType->getCanonicalType());
27602788
}
27612789

@@ -2773,6 +2801,48 @@ BEGIN_CAN_TYPE_WRAPPER(GenericFunctionType, AnyFunctionType)
27732801
}
27742802
END_CAN_TYPE_WRAPPER(GenericFunctionType, AnyFunctionType)
27752803

2804+
inline CanAnyFunctionType
2805+
CanAnyFunctionType::get(CanGenericSignature signature,
2806+
CanType input, CanType result) {
2807+
return get(signature, input, result, ExtInfo());
2808+
}
2809+
2810+
inline CanAnyFunctionType
2811+
CanAnyFunctionType::get(CanGenericSignature signature,
2812+
CanType input, CanType result, const ExtInfo &extInfo) {
2813+
if (signature) {
2814+
return CanGenericFunctionType::get(signature, input, result, extInfo);
2815+
} else {
2816+
return CanFunctionType::get(input, result, extInfo);
2817+
}
2818+
}
2819+
2820+
inline CanAnyFunctionType
2821+
CanAnyFunctionType::get(CanGenericSignature signature, CanParamArrayRef params,
2822+
CanType result, const ExtInfo &extInfo) {
2823+
if (signature) {
2824+
return CanGenericFunctionType::get(signature, params, result, extInfo);
2825+
} else {
2826+
return CanFunctionType::get(params, result, extInfo);
2827+
}
2828+
}
2829+
2830+
inline GenericSignature *AnyFunctionType::getOptGenericSignature() const {
2831+
if (auto genericFn = dyn_cast<GenericFunctionType>(this)) {
2832+
return genericFn->getGenericSignature();
2833+
} else {
2834+
return nullptr;
2835+
}
2836+
}
2837+
2838+
inline CanGenericSignature CanAnyFunctionType::getOptGenericSignature() const {
2839+
if (auto genericFn = dyn_cast<GenericFunctionType>(*this)) {
2840+
return genericFn.getGenericSignature();
2841+
} else {
2842+
return CanGenericSignature();
2843+
}
2844+
}
2845+
27762846
/// Conventions for passing arguments as parameters.
27772847
enum class ParameterConvention {
27782848
/// This argument is passed indirectly, i.e. by directly passing the address

include/swift/Basic/ArrayRefView.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ class ArrayRefView {
9393
Projected front() const { return Project(Array.front()); }
9494
Projected back() const { return Project(Array.back()); }
9595

96+
ArrayRefView drop_back(unsigned count = 1) const {
97+
return ArrayRefView(Array.drop_back(count));
98+
}
99+
96100
ArrayRefView slice(unsigned start) const {
97101
return ArrayRefView(Array.slice(start));
98102
}

0 commit comments

Comments
 (0)