 #       ^.___ 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

  else
    to

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

  # console.log (JSON.stringify type.type)
  ctx.extendSubstitution matchType inferredType.type, type.type#(substitute ctx.substitution, type).type
  # console.log "after", (printType inferredType.type)

  reduceConstraints ctx, inferredType.constraints
  # We also need to match dependent variables
  for c1 in inferredType.constraints
    for c2 in type.constraints
      constraintsEqual c1, c2
  #(substitute ctx.substitution, inferredType).constraints
  inferredType.constraints

