mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
We were dropping the substitutions required to call the default argument generator on the floor, when the correct solution is to remap them to substitutions in terms of the base class signature. Fixes <rdar://problem/29721571>.
99 lines
3.5 KiB
C++
99 lines
3.5 KiB
C++
//===--- SubstitutionMap.h - Swift Substitution Map ASTs --------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2016 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 SubstitutionMap class.
|
|
//
|
|
// This is a data structure type describing the mapping of abstract types to
|
|
// replacement types, together with associated conformances to use for deriving
|
|
// nested types.
|
|
//
|
|
// Depending on how the SubstitutionMap is constructed, the abstract types are
|
|
// either archetypes or interface types. Care must be exercised to only look up
|
|
// one or the other.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef SWIFT_AST_SUBSTITUTION_MAP_H
|
|
#define SWIFT_AST_SUBSTITUTION_MAP_H
|
|
|
|
#include "swift/AST/ProtocolConformanceRef.h"
|
|
#include "swift/AST/Type.h"
|
|
#include "llvm/ADT/ArrayRef.h"
|
|
#include "llvm/ADT/DenseMap.h"
|
|
#include "llvm/ADT/Optional.h"
|
|
#include "llvm/ADT/SmallVector.h"
|
|
|
|
namespace swift {
|
|
|
|
class SubstitutableType;
|
|
|
|
class SubstitutionMap {
|
|
using ParentType = std::pair<CanType, AssociatedTypeDecl *>;
|
|
|
|
llvm::DenseMap<SubstitutableType *, Type> subMap;
|
|
llvm::DenseMap<TypeBase *, ArrayRef<ProtocolConformanceRef>> conformanceMap;
|
|
llvm::DenseMap<TypeBase *, SmallVector<ParentType, 1>> parentMap;
|
|
|
|
Optional<ProtocolConformanceRef>
|
|
lookupConformance(ProtocolDecl *proto,
|
|
ArrayRef<ProtocolConformanceRef> conformances) const;
|
|
|
|
template<typename Fn>
|
|
Optional<ProtocolConformanceRef> forEachParent(CanType type, Fn fn) const;
|
|
|
|
public:
|
|
Optional<ProtocolConformanceRef>
|
|
lookupConformance(CanType type, ProtocolDecl *proto) const;
|
|
|
|
const llvm::DenseMap<SubstitutableType *, Type> &getMap() const {
|
|
return subMap;
|
|
}
|
|
|
|
/// Retrieve the conformances for the given type.
|
|
ArrayRef<ProtocolConformanceRef> getConformances(CanType type) const;
|
|
|
|
void addSubstitution(CanType type, Type replacement);
|
|
|
|
void addConformances(CanType type, ArrayRef<ProtocolConformanceRef> conformances);
|
|
|
|
void addParent(CanType type, CanType parent,
|
|
AssociatedTypeDecl *assocType);
|
|
|
|
bool empty() const {
|
|
return subMap.empty();
|
|
}
|
|
|
|
/// Given that 'derivedDecl' is an override of 'baseDecl' in a subclass,
|
|
/// and 'derivedSubs' is a set of substitutions written in terms of the
|
|
/// generic signature of 'derivedDecl', produce a set of substitutions
|
|
/// written in terms of the generic signature of 'baseDecl'.
|
|
static SubstitutionMap
|
|
getOverrideSubstitutions(const ValueDecl *baseDecl,
|
|
const ValueDecl *derivedDecl,
|
|
Optional<SubstitutionMap> derivedSubs,
|
|
LazyResolver *resolver);
|
|
|
|
/// Variant of the above for when we have the generic signatures but not
|
|
/// the decls for 'derived' and 'base'.
|
|
static SubstitutionMap
|
|
getOverrideSubstitutions(const ClassDecl *baseClass,
|
|
const ClassDecl *derivedClass,
|
|
GenericSignature *baseSig,
|
|
GenericSignature *derivedSig,
|
|
Optional<SubstitutionMap> derivedSubs,
|
|
LazyResolver *resolver);
|
|
};
|
|
|
|
} // end namespace swift
|
|
|
|
#endif
|