test: Add a case for resources used through lets

A hypothetical case discussed in the WG call, which I wasn't entirely sure was going to work. It does.

Change-Id: I855f1e02af2fe62214e3fb964f6937e3d88016eb
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/59021
Auto-Submit: Ben Clayton <bclayton@google.com>
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/test/let/handles/texture_sampler.wgsl b/test/let/handles/texture_sampler.wgsl
new file mode 100644
index 0000000..56428b9
--- /dev/null
+++ b/test/let/handles/texture_sampler.wgsl
@@ -0,0 +1,15 @@
+[[group(0), binding(0)]] var t : texture_2d<f32>;
+[[group(0), binding(1)]] var s : sampler;
+
+[[stage(fragment)]]
+fn main() {
+  let x = t;
+  let a = s;
+  ignore(1);
+  let y = x;
+  let b = a;
+  ignore(2);
+  let z = y;
+  let c = b;
+  ignore(textureSample(z, c, vec2<f32>(1., 2.)));
+}
diff --git a/test/let/handles/texture_sampler.wgsl.expected.hlsl b/test/let/handles/texture_sampler.wgsl.expected.hlsl
new file mode 100644
index 0000000..9926644
--- /dev/null
+++ b/test/let/handles/texture_sampler.wgsl.expected.hlsl
@@ -0,0 +1,13 @@
+Texture2D<float4> t : register(t0, space0);
+SamplerState s : register(s1, space0);
+
+void main() {
+  const Texture2D<float4> x = t;
+  const SamplerState a = s;
+  1;
+  const Texture2D<float4> y = x;
+  const SamplerState b = a;
+  2;
+  y.Sample(b, float2(1.0f, 2.0f));
+  return;
+}
diff --git a/test/let/handles/texture_sampler.wgsl.expected.msl b/test/let/handles/texture_sampler.wgsl.expected.msl
new file mode 100644
index 0000000..4c001ef
--- /dev/null
+++ b/test/let/handles/texture_sampler.wgsl.expected.msl
@@ -0,0 +1,16 @@
+#include <metal_stdlib>
+
+using namespace metal;
+fragment void tint_symbol(texture2d<float, access::sample> tint_symbol_1 [[texture(0)]], sampler tint_symbol_2 [[sampler(1)]]) {
+  texture2d<float, access::sample> const x = tint_symbol_1;
+  sampler const a = tint_symbol_2;
+  (void) 1;
+  texture2d<float, access::sample> const y = x;
+  sampler const b = a;
+  (void) 2;
+  texture2d<float, access::sample> const z = y;
+  sampler const c = b;
+  (void) z.sample(c, float2(1.0f, 2.0f));
+  return;
+}
+
diff --git a/test/let/handles/texture_sampler.wgsl.expected.spvasm b/test/let/handles/texture_sampler.wgsl.expected.spvasm
new file mode 100644
index 0000000..3907162
--- /dev/null
+++ b/test/let/handles/texture_sampler.wgsl.expected.spvasm
@@ -0,0 +1,42 @@
+; SPIR-V
+; Version: 1.3
+; Generator: Google Tint Compiler; 0
+; Bound: 28
+; Schema: 0
+               OpCapability Shader
+               OpMemoryModel Logical GLSL450
+               OpEntryPoint Fragment %main "main"
+               OpExecutionMode %main OriginUpperLeft
+               OpName %t "t"
+               OpName %s "s"
+               OpName %main "main"
+               OpDecorate %t DescriptorSet 0
+               OpDecorate %t Binding 0
+               OpDecorate %s DescriptorSet 0
+               OpDecorate %s Binding 1
+      %float = OpTypeFloat 32
+          %3 = OpTypeImage %float 2D 0 0 0 1 Unknown
+%_ptr_UniformConstant_3 = OpTypePointer UniformConstant %3
+          %t = OpVariable %_ptr_UniformConstant_3 UniformConstant
+          %7 = OpTypeSampler
+%_ptr_UniformConstant_7 = OpTypePointer UniformConstant %7
+          %s = OpVariable %_ptr_UniformConstant_7 UniformConstant
+       %void = OpTypeVoid
+          %8 = OpTypeFunction %void
+        %int = OpTypeInt 32 1
+      %int_1 = OpConstant %int 1
+      %int_2 = OpConstant %int 2
+    %v4float = OpTypeVector %float 4
+         %22 = OpTypeSampledImage %3
+    %v2float = OpTypeVector %float 2
+    %float_1 = OpConstant %float 1
+    %float_2 = OpConstant %float 2
+         %27 = OpConstantComposite %v2float %float_1 %float_2
+       %main = OpFunction %void None %8
+         %11 = OpLabel
+         %12 = OpLoad %3 %t
+         %13 = OpLoad %7 %s
+         %23 = OpSampledImage %22 %12 %13
+         %20 = OpImageSampleImplicitLod %v4float %23 %27
+               OpReturn
+               OpFunctionEnd
diff --git a/test/let/handles/texture_sampler.wgsl.expected.wgsl b/test/let/handles/texture_sampler.wgsl.expected.wgsl
new file mode 100644
index 0000000..29a81ae
--- /dev/null
+++ b/test/let/handles/texture_sampler.wgsl.expected.wgsl
@@ -0,0 +1,16 @@
+[[group(0), binding(0)]] var t : texture_2d<f32>;
+
+[[group(0), binding(1)]] var s : sampler;
+
+[[stage(fragment)]]
+fn main() {
+  let x = t;
+  let a = s;
+  ignore(1);
+  let y = x;
+  let b = a;
+  ignore(2);
+  let z = y;
+  let c = b;
+  ignore(textureSample(z, c, vec2<f32>(1.0, 2.0)));
+}