001    /*
002     * Copyright 2010-2015 JetBrains s.r.o.
003     *
004     * Licensed under the Apache License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    
017    package org.jetbrains.kotlin.resolve;
018    
019    import com.google.common.collect.Lists;
020    import com.intellij.psi.PsiElement;
021    import kotlin.Pair;
022    import org.jetbrains.annotations.NotNull;
023    import org.jetbrains.annotations.Nullable;
024    import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
025    import org.jetbrains.kotlin.descriptors.*;
026    import org.jetbrains.kotlin.diagnostics.rendering.Renderers;
027    import org.jetbrains.kotlin.name.Name;
028    import org.jetbrains.kotlin.psi.*;
029    import org.jetbrains.kotlin.resolve.calls.callUtil.CallUtilKt;
030    import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystem;
031    import org.jetbrains.kotlin.resolve.calls.inference.ConstraintSystemCompleter;
032    import org.jetbrains.kotlin.resolve.calls.inference.TypeVariableKt;
033    import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
034    import org.jetbrains.kotlin.resolve.calls.results.OverloadResolutionResults;
035    import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowInfo;
036    import org.jetbrains.kotlin.resolve.scopes.JetScopeUtils;
037    import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
038    import org.jetbrains.kotlin.resolve.scopes.LexicalScopeImpl;
039    import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
040    import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
041    import org.jetbrains.kotlin.resolve.validation.OperatorValidator;
042    import org.jetbrains.kotlin.resolve.validation.SymbolUsageValidator;
043    import org.jetbrains.kotlin.types.*;
044    import org.jetbrains.kotlin.types.checker.KotlinTypeChecker;
045    import org.jetbrains.kotlin.types.expressions.ExpressionTypingContext;
046    import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices;
047    import org.jetbrains.kotlin.types.expressions.FakeCallResolver;
048    import org.jetbrains.kotlin.util.slicedMap.WritableSlice;
049    
050    import java.util.Collections;
051    import java.util.List;
052    
053    import static org.jetbrains.kotlin.diagnostics.Errors.*;
054    import static org.jetbrains.kotlin.psi.KtPsiFactoryKt.KtPsiFactory;
055    import static org.jetbrains.kotlin.resolve.BindingContext.*;
056    import static org.jetbrains.kotlin.resolve.calls.inference.constraintPosition.ConstraintPositionKind.FROM_COMPLETER;
057    import static org.jetbrains.kotlin.types.TypeUtils.NO_EXPECTED_TYPE;
058    import static org.jetbrains.kotlin.types.TypeUtils.noExpectedType;
059    import static org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.createFakeExpressionOfType;
060    
061    public class DelegatedPropertyResolver {
062    
063        public static final Name PROPERTY_DELEGATED_FUNCTION_NAME = Name.identifier("propertyDelegated");
064        public static final Name GETTER_NAME = Name.identifier("getValue");
065        public static final Name SETTER_NAME = Name.identifier("setValue");
066    
067        public static final Name OLD_GETTER_NAME = Name.identifier("get");
068        public static final Name OLD_SETTER_NAME = Name.identifier("set");
069    
070        @NotNull private final ExpressionTypingServices expressionTypingServices;
071        @NotNull private final FakeCallResolver fakeCallResolver;
072        @NotNull private final KotlinBuiltIns builtIns;
073        @NotNull private final SymbolUsageValidator symbolUsageValidator;
074    
075        public DelegatedPropertyResolver(
076                @NotNull SymbolUsageValidator symbolUsageValidator,
077                @NotNull KotlinBuiltIns builtIns,
078                @NotNull FakeCallResolver fakeCallResolver,
079                @NotNull ExpressionTypingServices expressionTypingServices
080        ) {
081            this.symbolUsageValidator = symbolUsageValidator;
082            this.builtIns = builtIns;
083            this.fakeCallResolver = fakeCallResolver;
084            this.expressionTypingServices = expressionTypingServices;
085        }
086    
087        @Nullable
088        public KotlinType getDelegatedPropertyGetMethodReturnType(
089                @NotNull PropertyDescriptor propertyDescriptor,
090                @NotNull KtExpression delegateExpression,
091                @NotNull KotlinType delegateType,
092                @NotNull BindingTrace trace,
093                @NotNull LexicalScope delegateFunctionsScope
094        ) {
095            resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, true);
096            ResolvedCall<FunctionDescriptor> resolvedCall =
097                    trace.getBindingContext().get(DELEGATED_PROPERTY_RESOLVED_CALL, propertyDescriptor.getGetter());
098            return resolvedCall != null ? resolvedCall.getResultingDescriptor().getReturnType() : null;
099        }
100    
101        public void resolveDelegatedPropertyGetMethod(
102                @NotNull PropertyDescriptor propertyDescriptor,
103                @NotNull KtExpression delegateExpression,
104                @NotNull KotlinType delegateType,
105                @NotNull BindingTrace trace,
106                @NotNull LexicalScope delegateFunctionsScope
107        ) {
108            KotlinType returnType = getDelegatedPropertyGetMethodReturnType(
109                    propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope);
110            KotlinType propertyType = propertyDescriptor.getType();
111    
112            /* Do not check return type of get() method of delegate for properties with DeferredType because property type is taken from it */
113            if (!(propertyType instanceof DeferredType) && returnType != null && !KotlinTypeChecker.DEFAULT.isSubtypeOf(returnType, propertyType)) {
114                Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, propertyDescriptor.getGetter());
115                assert call != null : "Call should exists for " + propertyDescriptor.getGetter();
116                trace.report(DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH
117                                     .on(delegateExpression, renderCall(call, trace.getBindingContext()), propertyDescriptor.getType(), returnType));
118            }
119        }
120    
121        public void resolveDelegatedPropertySetMethod(
122                @NotNull PropertyDescriptor propertyDescriptor,
123                @NotNull KtExpression delegateExpression,
124                @NotNull KotlinType delegateType,
125                @NotNull BindingTrace trace,
126                @NotNull LexicalScope delegateFunctionsScope
127        ) {
128            resolveDelegatedPropertyConventionMethod(propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, false);
129        }
130    
131        @NotNull
132        private static KtExpression createExpressionForProperty(@NotNull KtPsiFactory psiFactory) {
133            return psiFactory.createExpression("null as " + KotlinBuiltIns.FQ_NAMES.kProperty.asSingleFqName().asString() + "<*>");
134        }
135    
136        public void resolveDelegatedPropertyPDMethod(
137                @NotNull PropertyDescriptor propertyDescriptor,
138                @NotNull KtExpression delegateExpression,
139                @NotNull KotlinType delegateType,
140                @NotNull BindingTrace trace,
141                @NotNull LexicalScope delegateFunctionsScope
142        ) {
143            TemporaryBindingTrace traceToResolvePDMethod = TemporaryBindingTrace.create(trace, "Trace to resolve propertyDelegated method in delegated property");
144            ExpressionTypingContext context = ExpressionTypingContext.newContext(
145                    traceToResolvePDMethod, delegateFunctionsScope,
146                    DataFlowInfo.EMPTY, TypeUtils.NO_EXPECTED_TYPE);
147    
148            KtPsiFactory psiFactory = KtPsiFactory(delegateExpression);
149            List<KtExpression> arguments = Collections.singletonList(createExpressionForProperty(psiFactory));
150            ExpressionReceiver receiver = ExpressionReceiver.Companion.create(delegateExpression, delegateType, trace.getBindingContext());
151    
152            Pair<Call, OverloadResolutionResults<FunctionDescriptor>> resolutionResult =
153                    fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, PROPERTY_DELEGATED_FUNCTION_NAME, delegateExpression);
154    
155            Call call = resolutionResult.getFirst();
156            OverloadResolutionResults<FunctionDescriptor> functionResults = resolutionResult.getSecond();
157    
158            if (!functionResults.isSuccess()) {
159                String expectedFunction = renderCall(call, traceToResolvePDMethod.getBindingContext());
160                if (functionResults.isIncomplete() || functionResults.isSingleResult() ||
161                    functionResults.getResultCode() == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) {
162                    trace.report(DELEGATE_PD_METHOD_NONE_APPLICABLE.on(delegateExpression, expectedFunction, functionResults.getResultingCalls()));
163                } else if (functionResults.isAmbiguity()) {
164                    trace.report(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY
165                                         .on(delegateExpression, expectedFunction, functionResults.getResultingCalls()));
166                }
167                return;
168            }
169    
170            trace.record(DELEGATED_PROPERTY_PD_RESOLVED_CALL, propertyDescriptor, functionResults.getResultingCall());
171        }
172    
173        /* Resolve getValue() or setValue() methods from delegate */
174        private void resolveDelegatedPropertyConventionMethod(
175                @NotNull PropertyDescriptor propertyDescriptor,
176                @NotNull KtExpression delegateExpression,
177                @NotNull KotlinType delegateType,
178                @NotNull BindingTrace trace,
179                @NotNull LexicalScope delegateFunctionsScope,
180                boolean isGet
181        ) {
182            PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
183            assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText();
184    
185            if (trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor) != null) return;
186    
187            OverloadResolutionResults<FunctionDescriptor> functionResults = getDelegatedPropertyConventionMethod(
188                    propertyDescriptor, delegateExpression, delegateType, trace, delegateFunctionsScope, isGet, true);
189            Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor);
190            assert call != null : "'getDelegatedPropertyConventionMethod' didn't record a call";
191    
192            if (!functionResults.isSuccess()) {
193                String expectedFunction = renderCall(call, trace.getBindingContext());
194                if (functionResults.isSingleResult() || functionResults.isIncomplete() ||
195                         functionResults.getResultCode() == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) {
196                    trace.report(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE
197                                         .on(delegateExpression, expectedFunction, functionResults.getResultingCalls()));
198                }
199                else if (functionResults.isAmbiguity()) {
200                    trace.report(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY
201                                                 .on(delegateExpression, expectedFunction, functionResults.getResultingCalls()));
202                }
203                else {
204                    trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType));
205                }
206                return;
207            }
208    
209            FunctionDescriptor resultingDescriptor = functionResults.getResultingDescriptor();
210    
211            ResolvedCall<FunctionDescriptor> resultingCall = functionResults.getResultingCall();
212            PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor);
213            if (declaration instanceof KtProperty) {
214                KtProperty property = (KtProperty) declaration;
215                KtPropertyDelegate delegate = property.getDelegate();
216                if (delegate != null) {
217                    PsiElement byKeyword = delegate.getByKeywordNode().getPsi();
218    
219                    if (!resultingDescriptor.isOperator()) {
220                        OperatorValidator.Companion.report(byKeyword, resultingDescriptor, trace);
221                    }
222    
223                    symbolUsageValidator.validateCall(resultingCall, resultingCall.getResultingDescriptor(), trace, byKeyword);
224                }
225            }
226            trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, resultingCall);
227        }
228    
229        /* Resolve getValue() or setValue() methods from delegate */
230        public OverloadResolutionResults<FunctionDescriptor> getDelegatedPropertyConventionMethod(
231                @NotNull PropertyDescriptor propertyDescriptor,
232                @NotNull KtExpression delegateExpression,
233                @NotNull KotlinType delegateType,
234                @NotNull BindingTrace trace,
235                @NotNull LexicalScope delegateFunctionsScope,
236                boolean isGet,
237                boolean isComplete
238        ) {
239            PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter();
240            assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText();
241    
242            KotlinType expectedType = isComplete && isGet && !(propertyDescriptor.getType() instanceof DeferredType)
243                                   ? propertyDescriptor.getType() : TypeUtils.NO_EXPECTED_TYPE;
244    
245            ExpressionTypingContext context = ExpressionTypingContext.newContext(
246                    trace, delegateFunctionsScope,
247                    DataFlowInfo.EMPTY, expectedType);
248    
249            boolean hasThis = propertyDescriptor.getExtensionReceiverParameter() != null || propertyDescriptor.getDispatchReceiverParameter() != null;
250    
251            List<KtExpression> arguments = Lists.newArrayList();
252            KtPsiFactory psiFactory = KtPsiFactory(delegateExpression);
253            arguments.add(psiFactory.createExpression(hasThis ? "this" : "null"));
254            arguments.add(createExpressionForProperty(psiFactory));
255    
256            if (!isGet) {
257                KtReferenceExpression fakeArgument = (KtReferenceExpression) createFakeExpressionOfType(delegateExpression.getProject(), trace,
258                                                                                                          "fakeArgument" + arguments.size(),
259                                                                                                        propertyDescriptor.getType());
260                arguments.add(fakeArgument);
261                List<ValueParameterDescriptor> valueParameters = accessor.getValueParameters();
262                trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0));
263            }
264    
265            Name functionName = isGet ? GETTER_NAME : SETTER_NAME;
266            ExpressionReceiver receiver = ExpressionReceiver.Companion.create(delegateExpression, delegateType, trace.getBindingContext());
267    
268            Pair<Call, OverloadResolutionResults<FunctionDescriptor>> resolutionResult =
269                    fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, functionName, delegateExpression);
270    
271            OverloadResolutionResults<FunctionDescriptor> resolutionResults = resolutionResult.getSecond();
272    
273            // Resolve get/set is getValue/setValue was not found. Temporary, for code migration
274            if (!resolutionResults.isSuccess() && !resolutionResults.isAmbiguity()) {
275                Name oldFunctionName = isGet ? OLD_GETTER_NAME : OLD_SETTER_NAME;
276                Pair<Call, OverloadResolutionResults<FunctionDescriptor>> additionalResolutionResult =
277                        fakeCallResolver.makeAndResolveFakeCallInContext(receiver, context, arguments, oldFunctionName, delegateExpression);
278                if (additionalResolutionResult.getSecond().isSuccess()) {
279                    FunctionDescriptor resultingDescriptor = additionalResolutionResult.getSecond().getResultingDescriptor();
280    
281                    PsiElement declaration = DescriptorToSourceUtils.descriptorToDeclaration(propertyDescriptor);
282                    if (declaration instanceof KtProperty) {
283                        KtProperty property = (KtProperty) declaration;
284                        KtPropertyDelegate delegate = property.getDelegate();
285                        if (delegate != null) {
286                            PsiElement byKeyword = delegate.getByKeywordNode().getPsi();
287    
288                            trace.report(DELEGATE_RESOLVED_TO_DEPRECATED_CONVENTION.on(
289                                    byKeyword, resultingDescriptor, delegateType, functionName.asString()));
290                        }
291                    }
292    
293                    trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, additionalResolutionResult.getFirst());
294                    return additionalResolutionResult.getSecond();
295                }
296            }
297    
298            trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, resolutionResult.getFirst());
299            return resolutionResults;
300        }
301    
302        private static String renderCall(@NotNull Call call, @NotNull BindingContext context) {
303            KtExpression calleeExpression = call.getCalleeExpression();
304            assert calleeExpression != null : "CalleeExpression should exists for fake call of convention method";
305            StringBuilder builder = new StringBuilder(calleeExpression.getText());
306            builder.append("(");
307            List<KotlinType> argumentTypes = Lists.newArrayList();
308            for (ValueArgument argument : call.getValueArguments()) {
309                argumentTypes.add(context.getType(argument.getArgumentExpression()));
310    
311            }
312            builder.append(Renderers.RENDER_COLLECTION_OF_TYPES.render(argumentTypes));
313            builder.append(")");
314            return builder.toString();
315        }
316    
317        @NotNull
318        public KotlinType resolveDelegateExpression(
319                @NotNull KtExpression delegateExpression,
320                @NotNull KtProperty property,
321                @NotNull PropertyDescriptor propertyDescriptor,
322                @NotNull LexicalScope scopeForDelegate,
323                @NotNull BindingTrace trace,
324                @NotNull DataFlowInfo dataFlowInfo
325        ) {
326            TemporaryBindingTrace traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property");
327            KtExpression calleeExpression = CallUtilKt.getCalleeExpressionIfAny(delegateExpression);
328            ConstraintSystemCompleter completer = createConstraintSystemCompleter(
329                    property, propertyDescriptor, delegateExpression, scopeForDelegate, trace);
330            if (calleeExpression != null) {
331                traceToResolveDelegatedProperty.record(CONSTRAINT_SYSTEM_COMPLETER, calleeExpression, completer);
332            }
333            KotlinType delegateType = expressionTypingServices.safeGetType(scopeForDelegate, delegateExpression, NO_EXPECTED_TYPE,
334                                                                           dataFlowInfo, traceToResolveDelegatedProperty);
335            traceToResolveDelegatedProperty.commit(new TraceEntryFilter() {
336                @Override
337                public boolean accept(@Nullable WritableSlice<?, ?> slice, Object key) {
338                    return slice != CONSTRAINT_SYSTEM_COMPLETER;
339                }
340            }, true);
341            return delegateType;
342        }
343    
344        @NotNull
345        private ConstraintSystemCompleter createConstraintSystemCompleter(
346                @NotNull KtProperty property,
347                @NotNull final PropertyDescriptor propertyDescriptor,
348                @NotNull final KtExpression delegateExpression,
349                @NotNull LexicalScope scopeForDelegate,
350                @NotNull final BindingTrace trace
351        ) {
352            final LexicalScope delegateFunctionsScope = JetScopeUtils.makeScopeForDelegateConventionFunctions(scopeForDelegate, propertyDescriptor);
353            final KotlinType expectedType = property.getTypeReference() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE;
354            return new ConstraintSystemCompleter() {
355                @Override
356                public void completeConstraintSystem(
357                        @NotNull ConstraintSystem.Builder constraintSystem, @NotNull ResolvedCall<?> resolvedCall
358                ) {
359                    KotlinType returnType = resolvedCall.getCandidateDescriptor().getReturnType();
360                    if (returnType == null) return;
361    
362                    TypeSubstitutor typeVariableSubstitutor =
363                            constraintSystem.getTypeVariableSubstitutors().get(TypeVariableKt.toHandle(resolvedCall.getCall()));
364                    assert typeVariableSubstitutor != null : "No substitutor in the system for call: " + resolvedCall.getCall();
365    
366                    TemporaryBindingTrace traceToResolveConventionMethods =
367                            TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods");
368                    OverloadResolutionResults<FunctionDescriptor>
369                            getMethodResults = getDelegatedPropertyConventionMethod(
370                                    propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope,
371                                    true, false
372                            );
373    
374                    if (conventionMethodFound(getMethodResults)) {
375                        FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor();
376                        KotlinType returnTypeOfGetMethod = descriptor.getReturnType();
377                        if (returnTypeOfGetMethod != null && !TypeUtils.noExpectedType(expectedType)) {
378                            KotlinType returnTypeInSystem = typeVariableSubstitutor.substitute(returnTypeOfGetMethod, Variance.INVARIANT);
379                            if (returnTypeInSystem != null) {
380                                constraintSystem.addSubtypeConstraint(returnTypeInSystem, expectedType, FROM_COMPLETER.position());
381                            }
382                        }
383                        addConstraintForThisValue(constraintSystem, typeVariableSubstitutor, descriptor);
384                    }
385                    if (!propertyDescriptor.isVar()) return;
386    
387                    // For the case: 'val v by d' (no declared type).
388                    // When we add a constraint for 'set' method for delegated expression 'd' we use a type of the declared variable 'v'.
389                    // But if the type isn't known yet, the constraint shouldn't be added (we try to infer the type of 'v' here as well).
390                    if (propertyDescriptor.getReturnType() instanceof DeferredType) return;
391    
392                    OverloadResolutionResults<FunctionDescriptor>
393                            setMethodResults = getDelegatedPropertyConventionMethod(
394                                    propertyDescriptor, delegateExpression, returnType, traceToResolveConventionMethods, delegateFunctionsScope,
395                                    false, false
396                            );
397    
398                    if (conventionMethodFound(setMethodResults)) {
399                        FunctionDescriptor descriptor = setMethodResults.getResultingDescriptor();
400                        List<ValueParameterDescriptor> valueParameters = descriptor.getValueParameters();
401                        if (valueParameters.size() == 3) {
402                            ValueParameterDescriptor valueParameterForThis = valueParameters.get(2);
403    
404                            if (!noExpectedType(expectedType)) {
405                                constraintSystem.addSubtypeConstraint(
406                                        expectedType,
407                                        typeVariableSubstitutor.substitute(valueParameterForThis.getType(), Variance.INVARIANT),
408                                        FROM_COMPLETER.position()
409                                );
410                            }
411                            addConstraintForThisValue(constraintSystem, typeVariableSubstitutor, descriptor);
412                        }
413                    }
414                }
415    
416                private boolean conventionMethodFound(@NotNull OverloadResolutionResults<FunctionDescriptor> results) {
417                    return results.isSuccess() ||
418                           (results.isSingleResult() &&
419                            results.getResultCode() == OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH);
420                }
421    
422                private void addConstraintForThisValue(
423                        ConstraintSystem.Builder constraintSystem,
424                        TypeSubstitutor typeVariableSubstitutor,
425                        FunctionDescriptor resultingDescriptor
426                ) {
427                    ReceiverParameterDescriptor extensionReceiver = propertyDescriptor.getExtensionReceiverParameter();
428                    ReceiverParameterDescriptor dispatchReceiver = propertyDescriptor.getDispatchReceiverParameter();
429                    KotlinType typeOfThis =
430                            extensionReceiver != null ? extensionReceiver.getType() :
431                            dispatchReceiver != null ? dispatchReceiver.getType() :
432                            builtIns.getNullableNothingType();
433    
434                    List<ValueParameterDescriptor> valueParameters = resultingDescriptor.getValueParameters();
435                    if (valueParameters.isEmpty()) return;
436                    ValueParameterDescriptor valueParameterForThis = valueParameters.get(0);
437    
438                    constraintSystem.addSubtypeConstraint(
439                            typeOfThis,
440                            typeVariableSubstitutor.substitute(valueParameterForThis.getType(), Variance.INVARIANT),
441                            FROM_COMPLETER.position()
442                    );
443                }
444            };
445        }
446    }