summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-07-17 00:15:15 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2016-07-21 22:24:07 +0300
commit1b3939de8059cd3a5bbd5cd53dc9e1d93644ebb4 (patch)
tree190eaa50b81fa24ca3be71b302fabeaf14b37f99
parent06ca302bc5b6c92191b8dc72c8784d1fade4a59f (diff)
Backport fix for #34209 to beta
-rw-r--r--src/librustc_typeck/check/_match.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs27
-rw-r--r--src/test/compile-fail/issue-34209.rs23
3 files changed, 51 insertions, 1 deletions
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 069a09183a7..6d27021832c 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -559,7 +559,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                             etc: bool, expected: Ty<'tcx>) {
         let tcx = self.tcx;
 
-        let def = tcx.expect_def(pat.id);
+        let def = self.finish_resolving_struct_path(path, pat.id, path.span);
         let variant = match self.def_struct_variant(def, path.span) {
             Some((_, variant)) => variant,
             None => {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 3bc90f05d25..e966e201bdb 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3704,6 +3704,33 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                expected);
     }
 
+    // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
+    // The newly resolved definition is written into `def_map`.
+    pub fn finish_resolving_struct_path(&self,
+                                        path: &hir::Path,
+                                        node_id: ast::NodeId,
+                                        span: Span)
+                                        -> Def
+    {
+        let path_res = self.tcx().expect_resolution(node_id);
+        if path_res.depth == 0 {
+            // If fully resolved already, we don't have to do anything.
+            path_res.base_def
+        } else {
+            let base_ty_end = path.segments.len() - path_res.depth;
+            let (_ty, def) = AstConv::finish_resolving_def_to_ty(self, self, span,
+                                                                 PathParamMode::Optional,
+                                                                 path_res.base_def,
+                                                                 None,
+                                                                 node_id,
+                                                                 &path.segments[..base_ty_end],
+                                                                 &path.segments[base_ty_end..]);
+            // Write back the new resolution.
+            self.tcx().def_map.borrow_mut().insert(node_id, def::PathResolution::new(def));
+            def
+        }
+    }
+
     pub fn resolve_ty_and_def_ufcs<'b>(&self,
                                        path_res: def::PathResolution,
                                        opt_self_ty: Option<Ty<'tcx>>,
diff --git a/src/test/compile-fail/issue-34209.rs b/src/test/compile-fail/issue-34209.rs
new file mode 100644
index 00000000000..a7879700b54
--- /dev/null
+++ b/src/test/compile-fail/issue-34209.rs
@@ -0,0 +1,23 @@
+// Copyright 2016 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.
+
+enum S {
+    A,
+}
+
+fn bug(l: S) {
+    match l {
+        S::B{ } => { },
+        //~^ ERROR ambiguous associated type; specify the type using the syntax `<S as Trait>::B`
+        //~| ERROR `S::B` does not name a struct or a struct variant
+    }
+}
+
+fn main () {}