anchor.diff:        hir.Expression.functionCall(
           getId(expression),
           target,
  +        expression.typeArguments?.arguments
  +                ?.map((argument) => astTypeToHirType(
  +                    queryContext, Tuple2(declarationId, argument.type)))
  +                ?.toList() ??
  +            [],
           hirArgumentMap,
  +      ),
  +    ]);
  +  }
  +
  +  Result<List<hir.Expression>, List<ReportedCompilerError>>
  +      lowerConstructorCall(
  +    ast.CallExpression expression,
  +    hir.IdentifierExpression target,
  +  ) {
  +    assert(target != null);
  +    assert(target.identifier is hir.ReflectionIdentifier,
  +        'target.identifier is not a ReflectionIdentifier: ${target.identifier}');
  +
  +    final classId = (target.identifier as hir.ReflectionIdentifier).id;
  +    // ignore: non_constant_identifier_names
  +    final class_ = getClassDeclarationHir(queryContext, classId);
  +    final constructorId =
  +        class_.innerDeclarationIds.singleWhere((id) => id.isConstructor);
  +
  +    final typeParameters = class_.typeParameters
  +        .map((p) => CandyType.parameter(p.name, classId))
  +        .toList();
  +    final typeArguments = expression.typeArguments?.arguments
  +            ?.map((a) =>
  +                astTypeToHirType(queryContext, Tuple2(declarationId, a.type)))
  +            ?.toList() ??
  +        [];
  +    final genericsMap = Map.fromEntries(
  +        typeParameters.zip<CandyType, MapEntry<CandyType, CandyType>>(
  +            typeArguments, (a, b) => MapEntry(a, b)));
  +
  +    final fields = class_.innerDeclarationIds
  +        .where((id) => id.isProperty)
  +        .map((id) => getPropertyDeclarationHir(queryContext, id))
  +        .where((field) => !field.isStatic)
  +        .toList();
  +    final valueParameterTypes =
  +        fields.map((field) => field.type.bakeGenerics(genericsMap)).toList();
  +    final valueArguments = expression.arguments;
  +
  +    final returnType = class_.thisType.bakeGenerics(genericsMap);
  +
  +    if (typeParameters.length != (typeArguments?.length ?? 0)) {
  +      return Error([
  +        CompilerError.wrongNumberOfTypeArguments(
  +          'Constructor expected ${typeParameters.length} type parameters, '
  +          'but you provided ${typeArguments?.length ?? 0}.',
  +          location: ErrorLocation(resourceId, expression.span),
  +        ),
  +      ]);
  +    }
  +
  +    if (!isValidExpressionType(returnType)) {
  +      return Error([
  +        CompilerError.invalidExpressionType(
  +          'Constructor has an invalid return type: $returnType. Expected: $expressionType',
  +          location: ErrorLocation(resourceId, expression.span),
  +        ),
  +      ]);
  +    }
  +
  +    if (valueParameterTypes.length < valueArguments.length) {
  +      return Error([
  +        CompilerError.tooManyArguments(
  +          'Too many constructor arguments.',
  +          location: ErrorLocation(resourceId, expression.span),
  +        )
  +      ]);
  +    }
  +
  +    if (valueParameterTypes.length > valueArguments.length) {
  +      return Error([
  +        CompilerError.missingArguments(
  +          'Too few constructor arguments.',
  +          location: ErrorLocation(resourceId, expression.span),
  +        )
  +      ]);
  +    }
  +
  +    final loweredArguments = [
  +      for (var i = 0; i < valueArguments.length; i++)
  +        innerExpressionContext(
  +          expressionType: Option.some(valueParameterTypes[i]),
  +        ).lowerUnambiguous(valueArguments[i].expression),
  +    ].merge();
  +    if (loweredArguments is Error) return loweredArguments;
  +    final arguments = loweredArguments.value;
  +
  +    return Ok([
  +      hir.Expression.functionCall(
  +        getId(expression),
  +        target,
  +        typeArguments,
  +        {
  +          for (var i = 0; i < arguments.length; i++)
  +            fields[i].name: arguments[i],
  +        },
         ),
       ]);
     }
  
positive.code:     if (targetVariants is Error) return targetVariants;
  
      final results = targetVariants.value.map((target) {
        if (target is hir.IdentifierExpression &&
            target.identifier is hir.PropertyIdentifier) {
          final identifier = target.identifier as hir.PropertyIdentifier;
  
negative.code:       ]);
      }
  
      final typeParameters = functionHir.typeParameters
          .map((p) => CandyType.parameter(p.name, functionId))
          .toList();
      final typeArguments = expression.typeArguments?.arguments
              ?.map((a) =>
                  astTypeToHirType(queryContext, Tuple2(declarationId, a.type)))
              ?.toList() ??
          [];
      final genericsMap = Map.fromEntries(
          typeParameters.zip<CandyType, MapEntry<CandyType, CandyType>>(
              typeArguments, (a, b) => MapEntry(a, b)));
      stderr.writeln('The generics map is $genericsMap.');
      stderr.writeln(
          'Fresh from the oven: ${functionHir.returnType.bakeGenerics(genericsMap)}');
  
      if (!isValidExpressionType(
          functionHir.returnType.bakeGenerics(genericsMap))) {
        return Error([
          CompilerError.internalError(
            'Function ${functionHir.name} has an invalid return type: ${functionHir.returnType}. '
            'Expected: $expressionType',
            location: ErrorLocation(resourceId, expression.span),
          ),
        ]);
  