Type rawInstantiate ( Env < AttrContext > env , Type site , Symbol m , ResultInfo resultInfo , List < Type > argtypes , List < Type > typeargtypes , boolean allowBoxing , boolean useVarargs , Warner warn ) throws Infer . InferenceException { Type mt = types . memberType ( site , m ) ; // tvars is the list of formal type variables for which type arguments // need to inferred. List < Type > tvars = List . nil ( ) ; if ( typeargtypes == null ) typeargtypes = List . nil ( ) ; if ( ! mt . hasTag ( FORALL ) && typeargtypes . nonEmpty ( ) ) { // This is not a polymorphic method, but typeargs are supplied // which is fine, see JLS 15.12.2.1 } else if ( mt . hasTag ( FORALL ) && typeargtypes . nonEmpty ( ) ) { ForAll pmt = ( ForAll ) mt ; if ( typeargtypes . length ( ) != pmt . tvars . length ( ) ) throw inapplicableMethodException . setMessage ( "arg.length.mismatch" ) ; // not enough args // Check type arguments are within bounds List < Type > formals = pmt . tvars ; List < Type > actuals = typeargtypes ; while ( formals . nonEmpty ( ) && actuals . nonEmpty ( ) ) { List < Type > bounds = types . subst ( types . getBounds ( ( TypeVar ) formals . head ) , pmt . tvars , typeargtypes ) ; for ( ; bounds . nonEmpty ( ) ; bounds = bounds . tail ) if ( ! types . isSubtypeUnchecked ( actuals . head , bounds . head , warn ) ) throw inapplicableMethodException . setMessage ( "explicit.param.do.not.conform.to.bounds" , actuals . head , bounds ) ; formals = formals . tail ; actuals = actuals . tail ; } mt = types . subst ( pmt . qtype , pmt . tvars , typeargtypes ) ; } else if ( mt . hasTag ( FORALL ) ) { ForAll pmt = ( ForAll ) mt ; List < Type > tvars1 = types . newInstances ( pmt . tvars ) ; tvars = tvars . appendList ( tvars1 ) ; mt = types . subst ( pmt . qtype , pmt . tvars , tvars1 ) ; } // find out whether we need to go the slow route via infer boolean instNeeded = tvars . tail != null ; /*inlined: tvars.nonEmpty()*/ for ( List < Type > l = argtypes ; l . tail != null /*inlined: l.nonEmpty()*/ && ! instNeeded ; l = l . tail ) { if ( l . head . hasTag ( FORALL ) ) instNeeded = true ; } if ( instNeeded ) return infer . instantiateMethod ( env , tvars , ( MethodType ) mt , resultInfo , ( MethodSymbol ) m , argtypes , allowBoxing , useVarargs , currentResolutionContext , warn ) ; DeferredAttr . DeferredAttrContext dc = currentResolutionContext . deferredAttrContext ( m , infer . emptyContext , resultInfo , warn ) ; currentResolutionContext . methodCheck . argumentsAcceptable ( env , dc , argtypes , mt . getParameterTypes ( ) , warn ) ; dc . complete ( ) ; return mt ; }
Try to instantiate the type of a method so that it fits given type arguments and argument types . If successful return the method s instantiated type else return null . The instantiation will take into account an additional leading formal parameter if the method is an instance method seen as a member of an under determined site . In this case we treat site as an additional parameter and the parameters of the class containing the method as additional type variables that get instantiated .