diff --git a/compiler/ast.nim b/compiler/ast.nim index 13f7890bcd2d8..0dd27254c65d4 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -399,6 +399,7 @@ type tfIsOutParam tfSendable tfImplicitStatic + tfWeakened # for tyDistinct means "weak distinct" TTypeFlags* = set[TTypeFlag] diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 5e2a5d0a72289..0bd2d27f95aa0 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -1712,10 +1712,11 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags, afterOverloading = f result = n result.typ() = elemType(arr) # Other types have a bit more of leeway - elif n[1].typ.skipTypes(abstractRange-{tyDistinct}).kind in + elif n[1].typ.skipTypes(abstractRange).kind in {tyInt..tyInt64, tyUInt..tyUInt64}: - result = n - result.typ() = elemType(arr) + if n[1].typ.kind != tyDistinct or tfWeakened in n[1].typ.flags: + result = n + result.typ() = elemType(arr) of tyTypeDesc: # The result so far is a tyTypeDesc bound # a tyGenericBody. The line below will substitute diff --git a/compiler/semtypes.nim b/compiler/semtypes.nim index b3839ef6333e7..5e3cc0eace30c 100644 --- a/compiler/semtypes.nim +++ b/compiler/semtypes.nim @@ -2291,6 +2291,11 @@ proc semTypeNode(c: PContext, n: PNode, prev: PType): PType = result = s.typ.base elif prev == nil: result = s.typ + elif prev.sym != nil and sfImportc in prev.sym.flags: + let tmp = newNode(nkDistinctTy) + tmp.add n + result = semDistinct(c, tmp, prev) + result.flags.incl tfWeakened else: let alias = maybeAliasType(c, s.typ, prev) if alias != nil: diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index e486f3a47f2c0..06dd1a3761959 100644 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -319,7 +319,7 @@ proc sumGeneric(t: PType): int = while true: case t.kind of tyAlias, tySink, tyNot: t = t.skipModifier - of tyArray, tyRef, tyPtr, tyDistinct, tyUncheckedArray, + of tyArray, tyRef, tyPtr, tyUncheckedArray, tyOpenArray, tyVarargs, tySet, tyRange, tySequence, tyLent, tyOwned, tyVar: t = t.elementType @@ -364,6 +364,9 @@ proc sumGeneric(t: PType): int = for _, a in t.paramTypes: result += sumGeneric(a) break + of tyDistinct: + result += ord(tfWeakened notin t.flags) + t = t.base else: if t.isConcept: result += t.reduceToBase.conceptBody.len @@ -1357,6 +1360,13 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, # Foo[templateCall(T)] shouldn't fail early if Foo has a constraint # and we can't evaluate `templateCall(T)` yet return isGeneric + of tyDistinct: + if f.kind != tyDistinct: + let coerceDistincts = c.coerceDistincts or tfWeakened in a.flags + if coerceDistincts: + inc c.inheritancePenalty + return typeRel(c, f, a.base, flags) + else: discard case f.kind @@ -1551,12 +1561,17 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, inc c.inheritancePenalty, depth + ord(c.inheritancePenalty < 0) result = isSubtype of tyDistinct: - a = a.skipTypes({tyOwned, tyGenericInst, tyRange}) + let af = a.skipTypes({tyOwned, tyGenericInst, tyRange}) + let coerceDistincts = c.coerceDistincts or tfWeakened in f.flags if a.kind == tyDistinct: - if sameDistinctTypes(f, a): result = isEqual + if sameDistinctTypes(f, af): result = isEqual #elif f.base.kind == tyAnything: result = isGeneric # issue 4435 - elif c.coerceDistincts: result = typeRel(c, f.base, a, flags) - elif c.coerceDistincts: result = typeRel(c, f.base, a, flags) + elif coerceDistincts: + inc c.inheritancePenalty + result = typeRel(c, f.base, a, flags) + elif coerceDistincts: + inc c.inheritancePenalty + result = typeRel(c, f.base, a, flags) of tySet: if a.kind == tySet: if f[0].kind != tyGenericParam and a[0].kind == tyEmpty: diff --git a/tests/distinct/tweakened.nim b/tests/distinct/tweakened.nim new file mode 100644 index 0000000000000..d818d09651eb1 --- /dev/null +++ b/tests/distinct/tweakened.nim @@ -0,0 +1,2 @@ +let bar = @[1.cdouble] +let foo: seq[float] = bar