diff --git a/cmake/SlangTarget.cmake b/cmake/SlangTarget.cmake index e9fde3ebfaf..aa87c16bfaa 100644 --- a/cmake/SlangTarget.cmake +++ b/cmake/SlangTarget.cmake @@ -414,7 +414,10 @@ function(slang_add_target dir type) # # Link and include from dependencies # - target_link_libraries(${target} PRIVATE ${ARG_LINK_WITH_PRIVATE}) + target_link_libraries( + ${target} + PRIVATE $ + ) target_link_libraries(${target} PUBLIC ${ARG_LINK_WITH_PUBLIC}) if(CMAKE_SYSTEM_NAME MATCHES "Darwin") @@ -448,14 +451,16 @@ function(slang_add_target dir type) get_filename_component(inc_abs ${inc} ABSOLUTE) target_include_directories( ${target} - PUBLIC "$" + PUBLIC + "$" + "$" ) endforeach() foreach(inc ${ARG_INCLUDE_DIRECTORIES_PRIVATE}) get_filename_component(inc_abs ${inc} ABSOLUTE) target_include_directories( ${target} - PRIVATE "$" + PRIVATE "$" ) endforeach() diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index 2865188b4db..ddc4ec4d5c9 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -7811,7 +7811,7 @@ void SemanticsDeclBasesVisitor::visitStructDecl(StructDecl* decl) { getSink()->diagnose( inheritanceDecl, - Diagnostics::baseOfStructMustBeStructOrInterface, + Diagnostics::baseOfStructMustBeInterface, decl, baseType); continue; @@ -7823,6 +7823,26 @@ void SemanticsDeclBasesVisitor::visitStructDecl(StructDecl* decl) } else if (auto baseStructDeclRef = baseDeclRef.as()) { + if (!isFromCoreModule(decl)) + { + // In Slang 2026, we no longer allow structs to inherit from other structs. + if (isSlang2026OrLater(this)) + { + getSink()->diagnose( + inheritanceDecl, + Diagnostics::baseOfStructMustBeInterface, + decl, + baseType); + } + else + { + // For legacy langauge versions, we still allow struct inheritance to avoid + // breaking existing code, but we will emit a warning to inform the user + // that this feature is unstable and may be removed in the future. + getSink()->diagnose(inheritanceDecl, Diagnostics::inheritanceUnstable); + } + } + // To simplify the task of reading and maintaining code, // we require that when a `struct` inherits from another // `struct`, the base `struct` is the first item in @@ -7845,7 +7865,7 @@ void SemanticsDeclBasesVisitor::visitStructDecl(StructDecl* decl) { getSink()->diagnose( inheritanceDecl, - Diagnostics::baseOfStructMustBeStructOrInterface, + Diagnostics::baseOfStructMustBeInterface, decl, baseType); continue; diff --git a/source/slang/slang-diagnostic-defs.h b/source/slang/slang-diagnostic-defs.h index f4741ab048c..4f0edf53b34 100644 --- a/source/slang/slang-diagnostic-defs.h +++ b/source/slang/slang-diagnostic-defs.h @@ -1662,8 +1662,8 @@ DIAGNOSTIC( DIAGNOSTIC( 30811, Error, - baseOfStructMustBeStructOrInterface, - "struct '$0' cannot inherit from type '$1' that is neither a struct nor an interface") + baseOfStructMustBeInterface, + "struct '$0' cannot inherit from non-interface type '$1'") DIAGNOSTIC( 30812, Error, @@ -1681,7 +1681,12 @@ DIAGNOSTIC( baseOfClassMustBeClassOrInterface, "class '$0' cannot inherit from type '$1' that is neither a class nor an interface") DIAGNOSTIC(30815, Error, circularityInExtension, "circular extension is not allowed.") - +DIAGNOSTIC( + 30816, + Warning, + inheritanceUnstable, + "support for inheritance is unstable and will be removed in future language versions, consider " + "using composition instead.") DIAGNOSTIC( 30820, Error, diff --git a/tests/diagnostics/inheritance-1.slang b/tests/diagnostics/inheritance-1.slang new file mode 100644 index 00000000000..c811623d88f --- /dev/null +++ b/tests/diagnostics/inheritance-1.slang @@ -0,0 +1,13 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): + +// Tests that we will diagnose a warning on struct inheritance being unstable +// before Slang 2026. + +#lang 2025 + +struct Base {} + +//CHECK: ([[# @LINE+1]]): warning 30816: +struct Derived : Base {} + +struct Base1 {} \ No newline at end of file diff --git a/tests/diagnostics/inheritance-2.slang b/tests/diagnostics/inheritance-2.slang new file mode 100644 index 00000000000..6b1bcfaffbb --- /dev/null +++ b/tests/diagnostics/inheritance-2.slang @@ -0,0 +1,10 @@ +//DIAGNOSTIC_TEST:SIMPLE(filecheck=CHECK): + +// Tests that we will diagnose an error on struct inheritance in language 2026 or later. + +#lang 2026 + +struct Base {} + +//CHECK: ([[# @LINE+1]]): error 30811: +struct Derived : Base {} diff --git a/tests/expected-failure.txt b/tests/expected-failure.txt index 22142e31d36..7283c8d97c3 100644 --- a/tests/expected-failure.txt +++ b/tests/expected-failure.txt @@ -5,5 +5,3 @@ tests/language-feature/saturated-cooperation/fuse.slang (vk) tests/bugs/byte-address-buffer-interlocked-add-f32.slang (vk) tests/ir/loop-unroll-0.slang.1 (vk) tests/hlsl-intrinsic/texture/float-atomics.slang (vk) -tests/hlsl/cbuffer-float3-offsets-aligned.slang.2 (vk) -tests/hlsl/cbuffer-float3-offsets-unaligned.slang.2 (vk) diff --git a/tests/hlsl-intrinsic/size-of/align-of.slang b/tests/hlsl-intrinsic/size-of/align-of.slang index c5be345c8ca..537949375d0 100644 --- a/tests/hlsl-intrinsic/size-of/align-of.slang +++ b/tests/hlsl-intrinsic/size-of/align-of.slang @@ -7,6 +7,8 @@ //TEST_INPUT:ubuffer(data=[0 0 0 0], stride=4):out,name outputBuffer +#pragma warning(disable:30816) + RWStructuredBuffer outputBuffer; enum Enum : int8_t diff --git a/tests/hlsl-intrinsic/size-of/size-of.slang b/tests/hlsl-intrinsic/size-of/size-of.slang index fc531bc4eff..965e0a4e5af 100644 --- a/tests/hlsl-intrinsic/size-of/size-of.slang +++ b/tests/hlsl-intrinsic/size-of/size-of.slang @@ -1,3 +1,4 @@ +#pragma warning(disable:30816) //TEST(compute):COMPARE_COMPUTE_EX:-cpu -compute -shaderobj //TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj diff --git a/tests/hlsl/cbuffer-float3-offsets-aligned.slang b/tests/hlsl/cbuffer-float3-offsets-aligned.slang index 7c548546a56..b1ae566b457 100644 --- a/tests/hlsl/cbuffer-float3-offsets-aligned.slang +++ b/tests/hlsl/cbuffer-float3-offsets-aligned.slang @@ -1,6 +1,6 @@ -//TEST:SIMPLE(filecheck=SPIRV): -target spirv -profile cs_6_2 -entry computeMain -line-directive-mode none -fvk-use-dx-layout +//TEST:SIMPLE(filecheck=SPIRV): -target spirv -emit-spirv-directly -profile cs_6_2 -entry computeMain -line-directive-mode none -fvk-use-dx-layout //TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -dx12 -use-dxil -profile cs_6_2 -Xslang... -Xdxc -fvk-use-dx-layout -Xdxc -enable-16bit-types -X. -output-using-type -//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -vk -profile cs_6_2 -Xslang... -fvk-use-dx-layout -X. -output-using-type +//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -vk -profile cs_6_2 -emit-spirv-directly -Xslang... -fvk-use-dx-layout -X. -output-using-type //TEST:REFLECTION(filecheck=REFLECT):-stage compute -entry computeMain -target spirv -profile cs_6_2 -no-codegen -line-directive-mode none -fvk-use-dx-layout //TEST_INPUT:ubuffer(stride=4, count=17):out,name=outputBuffer diff --git a/tests/hlsl/cbuffer-float3-offsets-unaligned.slang b/tests/hlsl/cbuffer-float3-offsets-unaligned.slang index c3824d1a2fd..920987343a6 100644 --- a/tests/hlsl/cbuffer-float3-offsets-unaligned.slang +++ b/tests/hlsl/cbuffer-float3-offsets-unaligned.slang @@ -1,6 +1,6 @@ -//TEST:SIMPLE(filecheck=SPIRV): -target spirv -profile cs_6_2 -entry computeMain -line-directive-mode none -fvk-use-dx-layout +//TEST:SIMPLE(filecheck=SPIRV): -target spirv -emit-spirv-directly -profile cs_6_2 -entry computeMain -line-directive-mode none -fvk-use-dx-layout //TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -dx12 -use-dxil -Xslang... -Xdxc -fvk-use-dx-layout -Xdxc -enable-16bit-types -X. -output-using-type -//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -vk -Xslang... -fvk-use-dx-layout -X. -output-using-type +//TEST(compute):COMPARE_COMPUTE_EX(filecheck-buffer=BUFFER):-slang -compute -vk -emit-spirv-directly -Xslang... -fvk-use-dx-layout -X. -output-using-type //TEST:REFLECTION(filecheck=REFLECT):-stage compute -entry computeMain -target spirv -profile cs_6_2 -no-codegen -line-directive-mode none -fvk-use-dx-layout // dxc: -T cs_6_2 -E computeMain -spirv -fvk-use-dx-layout -enable-16bit-types diff --git a/tests/initializer-list/struct-inherit.slang b/tests/initializer-list/struct-inherit.slang index 71487a74f87..642fb8f5447 100644 --- a/tests/initializer-list/struct-inherit.slang +++ b/tests/initializer-list/struct-inherit.slang @@ -3,6 +3,8 @@ //TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain //TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain +#pragma warning(disable:30816) + //TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer RWStructuredBuffer outputBuffer; diff --git a/tests/language-feature/inheritance/derived-struct-init-list.slang b/tests/language-feature/inheritance/derived-struct-init-list.slang index 51d3a9b6dee..213e5ee8e60 100644 --- a/tests/language-feature/inheritance/derived-struct-init-list.slang +++ b/tests/language-feature/inheritance/derived-struct-init-list.slang @@ -7,6 +7,8 @@ // an empty initializer list) is still possible // when using `struct` inheritance. +#pragma warning(disable:30816) + struct Base { int a = 1; diff --git a/tests/language-feature/inheritance/struct-inherit-interface-requirement.slang b/tests/language-feature/inheritance/struct-inherit-interface-requirement.slang index 84446aec30a..c6d30ed911f 100644 --- a/tests/language-feature/inheritance/struct-inherit-interface-requirement.slang +++ b/tests/language-feature/inheritance/struct-inherit-interface-requirement.slang @@ -5,6 +5,7 @@ // Test that a `struct` type can use an inherited // member to satisfy an interface requirement. +#pragma warning(disable:30816) interface ITweak { diff --git a/tests/language-feature/inheritance/struct-inheritance-imported.slang b/tests/language-feature/inheritance/struct-inheritance-imported.slang index 16816ec971f..b3399eaeb17 100644 --- a/tests/language-feature/inheritance/struct-inheritance-imported.slang +++ b/tests/language-feature/inheritance/struct-inheritance-imported.slang @@ -1,6 +1,6 @@ //TEST_IGNORE_FILE: // struct-inheritance-imported.slang - +#pragma warning(disable:30816) public struct Base { public int a; diff --git a/tests/language-feature/inheritance/struct-inheritance.slang b/tests/language-feature/inheritance/struct-inheritance.slang index d1611ddfc13..046a3f6b260 100644 --- a/tests/language-feature/inheritance/struct-inheritance.slang +++ b/tests/language-feature/inheritance/struct-inheritance.slang @@ -6,6 +6,8 @@ // Test that we can define a `struct` type // that inherits from another `struct`. +#pragma warning(disable:30816) + struct Base { int a; diff --git a/tests/language-feature/initializer-lists/inheritance-generic.slang b/tests/language-feature/initializer-lists/inheritance-generic.slang index d5b923afe48..71de21c4794 100644 --- a/tests/language-feature/initializer-lists/inheritance-generic.slang +++ b/tests/language-feature/initializer-lists/inheritance-generic.slang @@ -1,6 +1,9 @@ //TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj -vk //TEST(compute):COMPARE_COMPUTE(filecheck-buffer=BUFFER):-shaderobj +#pragma warning(disable:30816) + + struct Base { int a = 1; diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang index 4af5f284772..47858e59ce9 100644 --- a/tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang @@ -1,6 +1,8 @@ //TEST:SIMPLE(filecheck=CHECK): -target hlsl -stage compute -entry computeMain RWStructuredBuffer outputBuffer; +#pragma warning(disable:30816) + //CHECK: error 30851 struct DefaultStructNoInit_base diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang index e6f856a2120..c1de40b3c4b 100644 --- a/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang @@ -3,6 +3,9 @@ //TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain //TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain +#pragma warning(disable:30816) + + //TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer RWStructuredBuffer outputBuffer; diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang index eff3595f1ce..e11379cf351 100644 --- a/tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang @@ -3,6 +3,9 @@ //TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain //TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain +#pragma warning(disable:30816) + + //TEST_INPUT:ubuffer(data=[0 0], stride=4):out,name=outputBuffer RWStructuredBuffer outputBuffer; diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang index d6f9d36120d..97ebce04e8f 100644 --- a/tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang @@ -3,6 +3,9 @@ //TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain //TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain +#pragma warning(disable:30816) + + //TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer RWStructuredBuffer outputBuffer;