@@ -1892,7 +1892,7 @@ getGenericParamForHoleTypeVar(TypeVariableType *tv, const Solution &S) {
1892
1892
}
1893
1893
1894
1894
static Type replacePlaceholderType (PlaceholderType *placeholder,
1895
- const Solution &S) {
1895
+ const Solution &S, bool forCompletion ) {
1896
1896
auto &ctx = S.getConstraintSystem ().getASTContext ();
1897
1897
auto origTy = [&]() -> Type {
1898
1898
auto orig = placeholder->getOriginator ();
@@ -1920,13 +1920,23 @@ static Type replacePlaceholderType(PlaceholderType *placeholder,
1920
1920
if (isa<TypeVariableType>(replacement.getPointer ()))
1921
1921
return ErrorType::get (ctx);
1922
1922
1923
+ // For completion, we want to produce an archetype instead of an ErrorType
1924
+ // for a top-level generic parameter.
1925
+ // FIXME: This is pretty weird, we're producing a contextual type outside of
1926
+ // the context it exists in. We ought to see if we can make the completion
1927
+ // logic work with ErrorTypes instead.
1928
+ if (forCompletion) {
1929
+ if (auto *GP = replacement->getAs <GenericTypeParamType>())
1930
+ return GP->getDecl ()->getInnermostDeclContext ()->mapTypeIntoContext (GP);
1931
+ }
1923
1932
// Return an ErrorType with the replacement as the original type. Note that
1924
1933
// if we failed to replace a type variable with a generic parameter in a
1925
1934
// dependent member, `ErrorType::get` will fold it away.
1926
1935
return ErrorType::get (replacement);
1927
1936
}
1928
1937
1929
- Type Solution::simplifyType (Type type, bool wantInterfaceType) const {
1938
+ Type Solution::simplifyType (Type type, bool wantInterfaceType,
1939
+ bool forCompletion) const {
1930
1940
// If we've been asked for an interface type, start by mapping any archetypes
1931
1941
// out of context.
1932
1942
if (wantInterfaceType)
@@ -1966,7 +1976,7 @@ Type Solution::simplifyType(Type type, bool wantInterfaceType) const {
1966
1976
auto *typePtr = type.getPointer ();
1967
1977
1968
1978
if (auto *placeholder = dyn_cast<PlaceholderType>(typePtr))
1969
- return replacePlaceholderType (placeholder, *this );
1979
+ return replacePlaceholderType (placeholder, *this , forCompletion );
1970
1980
1971
1981
if (isa<TypeVariableType>(typePtr))
1972
1982
return ErrorType::get (ctx);
@@ -1980,136 +1990,8 @@ Type Solution::simplifyType(Type type, bool wantInterfaceType) const {
1980
1990
}
1981
1991
1982
1992
Type Solution::simplifyTypeForCodeCompletion (Type Ty) const {
1983
- auto &CS = getConstraintSystem ();
1984
-
1985
- // First, instantiate all type variables that we know, but don't replace
1986
- // placeholders by unresolved types.
1987
- Ty = CS.simplifyTypeImpl (Ty, [this ](TypeVariableType *typeVar) -> Type {
1988
- return getFixedType (typeVar);
1989
- });
1990
-
1991
- // Next, replace all placeholders by type variables. We know that all type
1992
- // variables now in the type originate from placeholders.
1993
- Ty = Ty.transformRec ([](Type type) -> std::optional<Type> {
1994
- if (auto *placeholder = type->getAs <PlaceholderType>()) {
1995
- if (auto *typeVar =
1996
- placeholder->getOriginator ().dyn_cast <TypeVariableType *>()) {
1997
- return Type (typeVar);
1998
- }
1999
- }
2000
-
2001
- return std::nullopt ;
2002
- });
2003
-
2004
- // Replace all type variables (which must come from placeholders) by their
2005
- // generic parameters. Because we call into simplifyTypeImpl
2006
- Ty = CS.simplifyTypeImpl (Ty, [&CS, this ](TypeVariableType *typeVar) -> Type {
2007
- // Code completion depends on generic parameter type being represented in
2008
- // terms of `ArchetypeType` since it's easy to extract protocol requirements
2009
- // from it.
2010
- auto getTypeVarAsArchetype = [](TypeVariableType *typeVar) -> Type {
2011
- if (auto *GP = typeVar->getImpl ().getGenericParameter ()) {
2012
- if (auto *GPD = GP->getDecl ()) {
2013
- return GPD->getInnermostDeclContext ()->mapTypeIntoContext (GP);
2014
- }
2015
- }
2016
- return Type ();
2017
- };
2018
-
2019
- if (auto archetype = getTypeVarAsArchetype (typeVar)) {
2020
- return archetype;
2021
- }
2022
-
2023
- // Sometimes the type variable itself doesn't have have an originator that
2024
- // can be replaced by an archetype but one of its equivalent type variable
2025
- // does.
2026
- // Search thorough all equivalent type variables, looking for one that can
2027
- // be replaced by a generic parameter.
2028
- std::vector<std::pair<TypeVariableType *, Type>> bindings (
2029
- typeBindings.begin (), typeBindings.end ());
2030
- // Make sure we iterate the bindings in a deterministic order.
2031
- llvm::sort (bindings, [](const std::pair<TypeVariableType *, Type> &lhs,
2032
- const std::pair<TypeVariableType *, Type> &rhs) {
2033
- return lhs.first ->getID () < rhs.first ->getID ();
2034
- });
2035
- for (auto binding : bindings) {
2036
- if (auto placeholder = binding.second ->getAs <PlaceholderType>()) {
2037
- if (placeholder->getOriginator ().dyn_cast <TypeVariableType *>() ==
2038
- typeVar) {
2039
- if (auto archetype = getTypeVarAsArchetype (binding.first )) {
2040
- return archetype;
2041
- }
2042
- }
2043
- }
2044
- }
2045
-
2046
- // When applying the logic below to get contextual types inside result
2047
- // builders, the code completion type variable is connected by a one-way
2048
- // constraint to a type variable in the buildBlock call, but that is not the
2049
- // type variable that represents the argument type. We need to find the type
2050
- // variable representing the argument to retrieve protocol requirements from
2051
- // it. Look for a ArgumentConversion constraint that allows us to retrieve
2052
- // the argument type var.
2053
- auto &cg = CS.getConstraintGraph ();
2054
-
2055
- // FIXME: The type variable is not going to be part of the constraint graph
2056
- // at this point unless it was created at the outermost decision level;
2057
- // otherwise it has already been rolled back! Work around this by creating
2058
- // an empty node if one doesn't exist.
2059
- cg.addTypeVariable (typeVar);
2060
-
2061
- for (auto argConstraint : cg[typeVar].getConstraints ()) {
2062
- if (argConstraint->getKind () == ConstraintKind::ArgumentConversion &&
2063
- argConstraint->getFirstType ()->getRValueType ()->isEqual (typeVar)) {
2064
- if (auto argTV =
2065
- argConstraint->getSecondType ()->getAs <TypeVariableType>()) {
2066
- if (auto archetype = getTypeVarAsArchetype (argTV)) {
2067
- return archetype;
2068
- }
2069
- }
2070
- }
2071
- }
2072
-
2073
- return typeVar;
2074
- });
2075
-
2076
- // Logic to determine the contextual type inside buildBlock result builders:
2077
- //
2078
- // When completing inside a result builder, the result builder
2079
- // @ViewBuilder var body: some View {
2080
- // Text("Foo")
2081
- // #^COMPLETE^#
2082
- // }
2083
- // gets rewritten to
2084
- // @ViewBuilder var body: some View {
2085
- // let $__builder2: Text
2086
- // let $__builder0 = Text("Foo")
2087
- // let $__builder1 = #^COMPLETE^#
2088
- // $__builder2 = ViewBuilder.buildBlock($__builder0, $__builder1)
2089
- // return $__builder2
2090
- // }
2091
- // Inside the constraint system
2092
- // let $__builder1 = #^COMPLETE^#
2093
- // gets type checked without context, so we can't know the contextual type for
2094
- // the code completion token. But we know that $__builder1 (and thus the type
2095
- // of #^COMPLETE^#) is used as the second argument to ViewBuilder.buildBlock,
2096
- // so we can extract the contextual type from that call. To do this, figure
2097
- // out the type variable that is used for $__builder1 in the buildBlock call.
2098
- // This type variable is connected to the type variable of $__builder1's
2099
- // definition by a one-way constraint.
2100
- if (auto TV = Ty->getAs <TypeVariableType>()) {
2101
- for (auto constraint : CS.getConstraintGraph ()[TV].getConstraints ()) {
2102
- if (constraint->getKind () == ConstraintKind::OneWayEqual &&
2103
- constraint->getSecondType ()->isEqual (TV)) {
2104
- return simplifyTypeForCodeCompletion (constraint->getFirstType ());
2105
- }
2106
- }
2107
- }
2108
-
2109
- // Remove any remaining type variables and placeholders
2110
- Ty = simplifyType (Ty);
2111
-
2112
- return Ty->getRValueType ();
1993
+ return simplifyType (Ty, /* wantInterfaceType*/ false , /* forCompletion*/ true )
1994
+ ->getRValueType ();
2113
1995
}
2114
1996
2115
1997
template <typename T>
0 commit comments