Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions tslang/lib/TypeScript/MLIRGenGenerics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -992,7 +992,12 @@ namespace mlirgen

if (typeParam.getValue().first->getConstraint())
{
auto reason = testConstraint(location, genericTypeGenContext.typeParamsWithArgs, typeParamValue.first, widenType, instantiateGenContext);
// a type predicate with a failed constraint is a compile-time type test that folds to
// `false` (below), not an error: don't warn for it
auto isTypePredicate = functionGenericTypeInfo->funcType.getNumResults() > 0
&& mlir::isa<mlir_ts::TypePredicateType>(functionGenericTypeInfo->funcType.getResult(0));
auto reason = testConstraint(location, genericTypeGenContext.typeParamsWithArgs, typeParamValue.first, widenType, instantiateGenContext,
/*reportFailure*/ !isTypePredicate);
if (reason == Reason::Failure)
{
LLVM_DEBUG(llvm::dbgs() << "\n!! skip. failed. should be resolved later\n";);
Expand All @@ -1001,11 +1006,10 @@ namespace mlirgen

if (reason == Reason::FailedConstraint)
{
if (functionGenericTypeInfo->funcType.getNumResults() > 0
&& mlir::isa<mlir_ts::TypePredicateType>(functionGenericTypeInfo->funcType.getResult(0)))
if (isTypePredicate)
{
return {
mlir::success(),
mlir::success(),
mlir_ts::FunctionType::get(builder.getContext(), {}, { getBooleanLiteral(false) }, false),
""
};
Expand Down
3 changes: 2 additions & 1 deletion tslang/lib/TypeScript/MLIRGenImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -12732,7 +12732,8 @@ class MLIRGenImpl
mlir::Type getSecondTypeFromTypeArguments(NodeArray<TypeNode> &typeArguments, const GenContext &genContext);

Reason testConstraint(mlir::Location location, llvm::StringMap<std::pair<TypeParameterDOM::TypePtr, mlir::Type>> &pairs,
const ts::TypeParameterDOM::TypePtr &typeParam, mlir::Type type, const GenContext &genContext);
const ts::TypeParameterDOM::TypePtr &typeParam, mlir::Type type, const GenContext &genContext,
bool reportFailure = true);

std::tuple<mlir::LogicalResult, IsGeneric> zipTypeParameterWithArgument(
mlir::Location location, llvm::StringMap<std::pair<TypeParameterDOM::TypePtr, mlir::Type>> &pairs,
Expand Down
12 changes: 8 additions & 4 deletions tslang/lib/TypeScript/MLIRGenTypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ namespace mlirgen
}

Reason MLIRGenImpl::testConstraint(mlir::Location location, llvm::StringMap<std::pair<TypeParameterDOM::TypePtr, mlir::Type>> &pairs,
const ts::TypeParameterDOM::TypePtr &typeParam, mlir::Type type, const GenContext &genContext) {
const ts::TypeParameterDOM::TypePtr &typeParam, mlir::Type type, const GenContext &genContext,
bool reportFailure) {
// we need to add current type into context to be able to use it in resolving "extends" constraints
GenContext constraintGenContext(genContext);
for (auto &typeParamWithArg : pairs)
Expand Down Expand Up @@ -340,8 +341,11 @@ namespace mlirgen
LLVM_DEBUG(llvm::dbgs() << "Type " << type << " does extend "
<< constraintType << ".";);

emitWarning(location, "") << "Type " << to_print(type) << " does not satisfy the constraint "
<< to_print(constraintType) << ".";
if (reportFailure)
{
emitWarning(location, "") << "Type " << to_print(type) << " does not satisfy the constraint "
<< to_print(constraintType) << ".";
}

return Reason::FailedConstraint;
}
Expand Down Expand Up @@ -407,7 +411,7 @@ namespace mlirgen
if (constraint)
{
// we ignore the test result but we need infered types, constraint will be checked later
testConstraint(location, pairs, typeParam, type, genContext);
testConstraint(location, pairs, typeParam, type, genContext, /*reportFailure*/ false);
}

return {mlir::success(), IsGeneric::False};
Expand Down
17 changes: 17 additions & 0 deletions tslang/test/tester/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2758,6 +2758,23 @@ add_test(NAME test-compile-integer-literal-truncation-quiet
set_tests_properties(test-compile-integer-literal-truncation-quiet
PROPERTIES FAIL_REGULAR_EXPRESSION "warning:|error:|Stack dump|Assertion failed")

# A type predicate whose constraint fails (the DefaultLib's `__is<V extends T, T>` / `__is_any`)
# folds to `false` without a warning; a real constraint violation warns once, not also from the
# inference pass ("Type 1 ..." beside "Type s32 ...").
add_test(NAME test-compile-constraint-warning-type-predicate
COMMAND $<TARGET_FILE:tslang> --emit=obj --no-default-lib -mm=none
"${PROJECT_SOURCE_DIR}/test/tester/constraint-warning/type_predicate.ts"
-o "${CMAKE_CURRENT_BINARY_DIR}/constraint-warning-type-predicate.obj")
set_tests_properties(test-compile-constraint-warning-type-predicate
PROPERTIES FAIL_REGULAR_EXPRESSION "does not satisfy the constraint|warning:|error:|Stack dump|Assertion failed")
add_test(NAME test-compile-constraint-warning-violation
COMMAND $<TARGET_FILE:tslang> --emit=obj --no-default-lib -mm=none
"${PROJECT_SOURCE_DIR}/test/tester/constraint-warning/violation.ts"
-o "${CMAKE_CURRENT_BINARY_DIR}/constraint-warning-violation.obj")
set_tests_properties(test-compile-constraint-warning-violation
PROPERTIES PASS_REGULAR_EXPRESSION "violation\\.ts:4:25: warning: Type s32 does not satisfy the constraint string\\."
FAIL_REGULAR_EXPRESSION "Type 1 does not satisfy|Stack dump|Assertion failed")

# A switch's case of another kind of primitive (a string for a number) is an error, as it can never
# match: the switch's value was cast to the case's type instead.
add_test(NAME test-compile-diagnostic-location-switch-case-type
Expand Down
26 changes: 26 additions & 0 deletions tslang/test/tester/constraint-warning/type_predicate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// A type predicate whose constraint fails is a compile-time type test that folds to `false`
// (the DefaultLib's `__is` / `__is_any`): the failure is the intended answer, not a warning.
function isOf<V extends T, T>(t: T): t is V { return true; }
function isAny<V extends never>(t: V): t is V { return true; }

function sameType<V, T>(t: T, v: V) {
if (isOf<V, T>(t)) {
return "same";
}

return "other";
}

function keyKind<K>(key: K) {
if (isAny(key)) {
return "any";
}

return "typed";
}

function main() {
print(sameType("a", 1.5));
print(sameType("a", "b"));
print(keyKind(1));
}
4 changes: 4 additions & 0 deletions tslang/test/tester/constraint-warning/violation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// A generic called with an argument that breaks its constraint warns once, from the final check
// (the inference pass that runs first doesn't report it).
function f<T extends string>(t: T) { return t; }
function main() { print(f(1)); }
Loading