Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixes variable initialization of concept types with ORC on Macos and Linux i386 #20380

Closed
wants to merge 3 commits into from

Conversation

ringabout
Copy link
Member

@ringabout ringabout commented Sep 18, 2022

ref #19972 (comment)

given a small test case

type
  stringTest = concept x
    x is string

let usedToFail: stringTest = "111"
echo usedToFail

After matching the concept type and the type of argument using paramTypesMatch, we can infer the type of usedToFail with string instead of keeping using tyConcept type. We don't need to use typeAllowed to check whether the concept is properly constructed because it is checked at the concept definition.

@ringabout ringabout closed this Sep 18, 2022
@ringabout ringabout reopened this Sep 18, 2022
@ringabout ringabout changed the title test #19972 fixes variable of concept types with ORC initialization Sep 19, 2022
@ringabout ringabout changed the title fixes variable of concept types with ORC initialization fixes variable initialization of concept types with ORC Sep 19, 2022
@ringabout ringabout marked this pull request as ready for review September 19, 2022 12:57
Comment on lines +485 to +486
if formal.kind == tyUserTypeClass:
result.typ = arg.typ
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see where concept types are resolved to concrete types. When it seemed to be a tyConcept type at the c code gen phase, not a string type. It causes difficulties for the ORC code generator, which initializes the string with a tyConcept type using static const which should have been a variable.

@Araq
Copy link
Member

Araq commented Sep 19, 2022

Please outline why this affects ORC.

@ringabout
Copy link
Member Author

ringabout commented Sep 19, 2022

type
  stringTest = concept x
    x is string

let usedToFail: stringTest = "111"
echo usedToFail

generates code like below

/Users//@mconcepts@stusertypeclasses.nim.c:209:81: error: initializer element is not a compile-time constant
 N_LIB_PRIVATE NIM_CONST NimStringV2 usedToFail__conceptsZtusertypeclasses_368 = TM__Zcmg9a6xw00tn7dapi0pbqQ_13;

which is not accepted by some C compilers => my first commit verifies that (cd90ec7) which only test the specified test with ORC but it failed. Here is the CI https://github.com/nim-lang/Nim/runs/8413141986

It seems to be specific to macos with C backend and Linux i386, probably related to the C compiler. But still I suppose it should be a concrete type instead of a tyConcept type at code gen phase.

@ringabout
Copy link
Member Author

ringabout commented Sep 19, 2022

Found it

proc potentialValueInit(p: BProc; v: PSym; value: PNode): Rope =
  if lfDynamicLib in v.loc.flags or sfThread in v.flags or p.hcrOn:
    result = nil
  elif sfGlobal in v.flags and value != nil and isDeepConstExpr(value, p.module.compileToCpp) and
      p.withinLoop == 0 and not containsGarbageCollectedRef(v.typ):
    #echo "New code produced for ", v.name.s, " ", p.config $ value.info
    result = genBracedInit(p, value, isConst = false, v.typ)
  else:
    result = nil

in potentialValueInit, the second branch (isDeepConstExpr) evaluates to true with a tyConcept type. Then genBracedInit gets called,

    of tyString, tyCstring:
      if optSeqDestructors in p.config.globalOptions and n.kind != nkNilLit and ty == tyString:
        result = genStringLiteralV2Const(p.module, n, isConst)
      else:
        var d: TLoc
        initLocExpr(p, n, d)
        result = rdLoc(d)

The snippet above is picked up from the genBracedInit proc, the code differs between refc and arc/orc. So genStringLiteralV2Const will be called for ORC and generates N_LIB_PRIVATE NIM_CONST NimStringV2 usedToFail__conceptsZtusertypeclasses_368 = TM__Zcmg9a6xw00tn7dapi0pbqQ_13; which gives an error error: initializer element is not a compile-time constant.

@ringabout ringabout requested a review from Araq September 19, 2022 13:29
@ringabout ringabout changed the title fixes variable initialization of concept types with ORC fixes variable initialization of concept types with ORC on Macos and Linux i386 Sep 19, 2022
@Varriount Varriount added the Requires Araq To Merge PR should only be merged by Araq label Sep 19, 2022
@Araq
Copy link
Member

Araq commented Sep 20, 2022

Shouldn't we fix isDeepConstExpr instead then?

@ringabout
Copy link
Member Author

ringabout commented Sep 20, 2022

After semVarOrLet, let usedToFail: string = "111" is transformed into let usedToFail: string; usedToFail = "111" while let usedToFail: stringTest = "111" still keeps this form. Should It probably need to be transformed first? Because the value is a stringLiteral(should have been a nkEmpty) so isDeepConst evaluates it to true. There seems to be nothing wrong with isDeepConst.

@ringabout ringabout closed this Aug 29, 2023
@ringabout ringabout deleted the pr_metatype branch August 29, 2023 14:25
@ringabout ringabout added the stale Staled PR/issues; remove the label after fixing them label Aug 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Requires Araq To Merge PR should only be merged by Araq stale Staled PR/issues; remove the label after fixing them
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants