about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-05-26 16:36:40 -0400
committerNiko Matsakis <niko@alum.mit.edu>2017-05-26 16:36:40 -0400
commit9d018400eda8add2da8b0e1bd0e28bbc42d73426 (patch)
tree0a25bf7d7967f2a0efc63f2ea40326c48dae44dc
parentc732446eddeb2d387763c7974d7e78217e44519a (diff)
downloadrust-9d018400eda8add2da8b0e1bd0e28bbc42d73426.tar.gz
rust-9d018400eda8add2da8b0e1bd0e28bbc42d73426.zip
extend `struct_tail` to operate over closures
-rw-r--r--src/librustc/ty/util.rs30
-rw-r--r--src/test/run-pass/issue-42210.rs29
2 files changed, 52 insertions, 7 deletions
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 01fed11fc97..eb7744e1213 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -266,13 +266,29 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// if not a structure at all. Corresponds to the only possible unsized
     /// field, and its type can be used to determine unsizing strategy.
     pub fn struct_tail(self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
-        while let TyAdt(def, substs) = ty.sty {
-            if !def.is_struct() {
-                break;
-            }
-            match def.struct_variant().fields.last() {
-                Some(f) => ty = f.ty(self, substs),
-                None => break,
+        loop {
+            match ty.sty {
+                ty::TyAdt(def, substs) => {
+                    if !def.is_struct() {
+                        break;
+                    }
+                    match def.struct_variant().fields.last() {
+                        Some(f) => ty = f.ty(self, substs),
+                        None => break,
+                    }
+                }
+
+                ty::TyTuple(tys, _) => {
+                    if let Some((&last_ty, _)) = tys.split_last() {
+                        ty = last_ty;
+                    } else {
+                        break;
+                    }
+                }
+
+                _ => {
+                    break;
+                }
             }
         }
         ty
diff --git a/src/test/run-pass/issue-42210.rs b/src/test/run-pass/issue-42210.rs
new file mode 100644
index 00000000000..ecdf78cd5bd
--- /dev/null
+++ b/src/test/run-pass/issue-42210.rs
@@ -0,0 +1,29 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// Regression test for #42210.
+
+// compile-flags: -g
+
+trait Foo {
+    fn foo() { }
+}
+
+struct Bar;
+
+trait Baz {
+}
+
+impl Foo for (Bar, Baz) { }
+
+
+fn main() {
+    <(Bar, Baz) as Foo>::foo()
+}