     # console.log "attached", (printType t2)
     newSubstitution()
   else if t1.QuantifiedVar and t2.QuantifiedVar # used when checking declared type
-    if t1.name isnt t2.name
+    if t1.var isnt t2.var
       unifyFail t1, t2
+    else
+      emptySubstitution()
   else if t1.TypeConstr and t2.TypeConstr and t1.name is t2.name
     emptySubstitution()
   else if t1.TypeApp and t2.TypeApp

  ctx.declareAsFinal name, scopeIndex
  return deferredConstraints or []

declaredTypeTooGeneral = (ctx, inferredType, updatedDeclaredType, declaredType) ->
  {fails: [{conflicts, types}]} = matchType inferredType.type.type, copyOrigin (updatedDeclaredType.type.type), declaredType.type.type
  [fromInferred, fromDeclared] = types
  [t1, t2] = sortBasedOnOriginPosition fromInferred, fromDeclared
  # Dont report for fake types
  declaringType = originOf fromDeclared
  if isFake declaringType
    declaringType.inferredType = fromInferred
  else
    inferred = "inferred #{printType fromInferred}"
    got = "got #{print declaringType}"

      message: "declared type is too general, " +
        if t1 is fromInferred then "#{inferred}, #{got}" else "#{got}, #{inferred}"
      conflicts: conflicts

replaceQuantifiedByOrigin = (type) ->
  if type.TypeApp
    new TypeApp (replaceQuantifiedByOrigin type.op),
      (replaceQuantifiedByOrigin type.arg)
  else if type.QuantifiedVar and type.origin
    new TypeVariable (print type.origin), star
  else
    type

topLevelExpression = (ctx, expression) ->
  ctx.bareDefine()
