 #       ^.___ not necessarily, we could have a tuple of functions or similar
 irDefinitionTranslate = (ctx, {type, expression, reference, bare}) ->
   finalType = type#substitute ctx.substitution, type
-  allConstraints = (addConstraintsFrom ctx,
-    {type, name: reference?.name, scopeIndex: reference?.scopeIndex}, finalType).constraints
+  # allConstraints = (addConstraintsFrom ctx,
+  #   {type, name: reference?.name, scopeIndex: reference?.scopeIndex}, finalType).constraints
+
   reducedConstraints =
-    # if declaredType = ctx.typeForId id
-    #   constraintsFromCanonicalType ctx, declaredType, finalType
-    # else
-      (reduceConstraints ctx, allConstraints).success
+    if reference
+      constraintsFromReference ctx, {type, name: reference.name, scopeIndex: reference.scopeIndex}
+    else
+      (reduceConstraints ctx, finalType.constraints).success
   if not reducedConstraints
     return jsNoop()
   if bare and _notEmpty reducedConstraints

          # log "type", name, binding.id, binding.scopeIndex
          deferredConstraints = inferType ctx, binding.id, canonicalType,
            allConstraints, binding.polymorphic, binding.scopeIndex
          addToMap allDeferredConstraints, binding.scopeIndex, deferredConstraints

  ctx.deferredBindings().length = 0 # clear


  else
    to

constraintsFromReference = (ctx, {name, type, scopeIndex}) ->
  if scopeIndex? and (typed = ctx.savedDeclaration name, scopeIndex) and
      typed.type and
      (_notEmpty typed.type.type.constraints)
    constraintsFromCanonicalType ctx, typed.type, type
  else
    []

constraintsFromCanonicalType = (ctx, canonicalType, type) ->
  inferredType = freshInstance ctx, canonicalType
  # console.log "canonicalType", canonicalType, type
