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