 
 # Returns deferred and retained constraints
 deferConstraints = (ctx, constraints, type) ->
+  result = tryDeferConstraints ctx, constraints, type
+  if result.error
+    ctx.extendSubstitution result.error
+  result
+
+tryDeferConstraints = (ctx, constraints, type) ->
   reducedConstraints = reduceConstraints ctx, constraints
   if not reducedConstraints.success
     return reducedConstraints

      isDeclaredConstraint = (c) ->
        entailed = entail ctx, unifiedType.constraints, c
      notDeclared = filter (__ _not, isDeclaredConstraint), checked = constraints #(substituteList ctx.substitution, constraints)
      {success, error} = deferConstraints ctx, notDeclared, currentType
      if error
        ctx.extendSubstitution error
      else
        [deferredConstraints, retainedConstraints] = success
        if _notEmpty retainedConstraints
          ctx.extendSubstitution substitutionFail "#{name}'s context is too weak, missing #{listOf (map printType, retainedConstraints)}"
  else
    if not ctx.isAtNonDeferrableDefinition()
      {success, error} = deferConstraints ctx,
        constraints#(substituteList ctx.substitution, constraints),
        currentType
      if error
        ctx.extendSubstitution error
        return
      [deferredConstraints, retainedConstraints] = success
      # Finalizing type again after possibly added substitution when defer constraints

    s: stringType
    c: charType
  [formatStringToken, args...] = _arguments call
  if not formatStringToken
    return malformed ctx, call, 'Format string required.'
  compiledArgs = termsCompile ctx, args
  if not all map _tea, args
    call.tea = toConstrained stringType
