@@ -1313,19 +1313,29 @@ const IR::Node *TypeInferenceBase::postorder(const IR::PathExpression *expressio
13131313 } else if (decl->is <IR::Declaration_Variable>()) {
13141314 setLeftValue (expression);
13151315 setLeftValue (getOriginal<IR::Expression>());
1316- } else if (decl->is <IR::Parameter>()) {
1317- auto paramDecl = decl->to <IR::Parameter>();
1316+ } else if (auto paramDecl = decl->to <IR::Parameter>()) {
13181317 if (paramDecl->direction == IR::Direction::InOut ||
13191318 paramDecl->direction == IR::Direction::Out) {
13201319 setLeftValue (expression);
13211320 setLeftValue (getOriginal<IR::Expression>());
13221321 } else if (paramDecl->direction == IR::Direction::None) {
13231322 setCompileTimeConstant (expression);
13241323 setCompileTimeConstant (getOriginal<IR::Expression>());
1324+ if (typeMap->externImplicitAssignType (paramDecl->type , true )) {
1325+ setLeftValue (expression);
1326+ setLeftValue (getOriginal<IR::Expression>());
1327+ }
13251328 }
1326- } else if (decl->is <IR::Declaration_Constant>() || decl->is <IR::Declaration_Instance>()) {
1329+ } else if (decl->is <IR::Declaration_Constant>()) {
1330+ setCompileTimeConstant (expression);
1331+ setCompileTimeConstant (getOriginal<IR::Expression>());
1332+ } else if (auto di = decl->to <IR::Declaration_Instance>()) {
13271333 setCompileTimeConstant (expression);
13281334 setCompileTimeConstant (getOriginal<IR::Expression>());
1335+ if (typeMap->externImplicitAssignType (di->type , true )) {
1336+ setLeftValue (expression);
1337+ setLeftValue (getOriginal<IR::Expression>());
1338+ }
13291339 } else if (decl->is <IR::Method>() || decl->is <IR::Function>()) {
13301340 type = getType (decl->getNode ());
13311341 // Each method invocation uses fresh type variables
@@ -1598,28 +1608,36 @@ const IR::Node *TypeInferenceBase::postorder(const IR::Member *expression) {
15981608 if (auto ts = type->to <IR::Type_SpecializedCanonical>()) type = ts->substituted ;
15991609
16001610 if (auto *ext = type->to <IR::Type_Extern>()) {
1601- auto call = findContext<IR::MethodCallExpression>();
1602- if (call == nullptr ) {
1603- typeError (" %1%: Methods can only be called" , expression);
1611+ setCompileTimeConstant (expression);
1612+ setCompileTimeConstant (getOriginal<IR::Expression>());
1613+ if (auto call = getParent<IR::MethodCallExpression>()) {
1614+ auto method = ext->lookupMethod (expression->member , call->arguments );
1615+ if (method == nullptr ) {
1616+ typeError (" %1%: extern %2% does not have method matching this call" , expression,
1617+ ext->name );
1618+ return expression;
1619+ }
1620+
1621+ const IR::Type *methodType = getType (method);
1622+ if (methodType == nullptr ) return expression;
1623+ // Each method invocation uses fresh type variables
1624+ methodType = cloneWithFreshTypeVariables (methodType->to <IR::IMayBeGenericType>());
1625+
1626+ setType (getOriginal (), methodType);
1627+ setType (expression, methodType);
16041628 return expression;
1605- }
1606- auto method = ext->lookupMethod (expression->member , call->arguments );
1607- if (method == nullptr ) {
1608- typeError (" %1%: extern %2% does not have method matching this call" , expression,
1609- ext->name );
1629+ } else if (auto cvt = typeMap->externImplicitReadType (ext)) {
1630+ if (cvt->is <IR::Type_StructLike>()) {
1631+ type = cvt;
1632+ // assume we'll convert to that and fall through
1633+ } else {
1634+ typeError (" %1%: Methods can only be called" , expression);
1635+ return expression;
1636+ }
1637+ } else {
1638+ typeError (" %1%: Methods can only be called" , expression);
16101639 return expression;
16111640 }
1612-
1613- const IR::Type *methodType = getType (method);
1614- if (methodType == nullptr ) return expression;
1615- // Each method invocation uses fresh type variables
1616- methodType = cloneWithFreshTypeVariables (methodType->to <IR::IMayBeGenericType>());
1617-
1618- setType (getOriginal (), methodType);
1619- setType (expression, methodType);
1620- setCompileTimeConstant (expression);
1621- setCompileTimeConstant (getOriginal<IR::Expression>());
1622- return expression;
16231641 }
16241642
16251643 bool inMethod = getParent<IR::MethodCallExpression>() != nullptr ;
0 commit comments