]> git.lizzy.rs Git - rust.git/commitdiff
Auto merge of #41777 - nikomatsakis:issue-41697-mir-dump-cycle, r=arielb1
authorbors <bors@rust-lang.org>
Tue, 9 May 2017 09:27:50 +0000 (09:27 +0000)
committerbors <bors@rust-lang.org>
Tue, 9 May 2017 09:27:50 +0000 (09:27 +0000)
dump-mir was causing cycles by invoking item-path-str at bad times

Workaround for now, but probably a better fix is to opt **in** to using the types for impls (if we do that at all; maybe filename/line is better).

Fixes #41697

src/librustc_mir/util/pretty.rs
src/test/run-pass/issue-41697.rs [new file with mode: 0644]

index 5f51888019b9d2cd2f34b1d4ba2e4a55d8b08077..14f277d1767bbc3faf3915ddec606226c46d6327 100644 (file)
@@ -13,6 +13,7 @@
 use rustc::mir::*;
 use rustc::mir::transform::{MirSuite, MirPassIndex, MirSource};
 use rustc::ty::TyCtxt;
+use rustc::ty::item_path;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::indexed_vec::{Idx};
 use std::fmt::Display;
@@ -48,7 +49,9 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         return;
     }
 
-    let node_path = tcx.item_path_str(tcx.hir.local_def_id(source.item_id()));
+    let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below
+        tcx.item_path_str(tcx.hir.local_def_id(source.item_id()))
+    });
     dump_matched_mir_node(tcx, pass_num, pass_name, &node_path,
                           disambiguator, source, mir);
     for (index, promoted_mir) in mir.promoted.iter_enumerated() {
@@ -67,7 +70,9 @@ pub fn dump_enabled<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         Some(ref filters) => filters,
     };
     let node_id = source.item_id();
-    let node_path = tcx.item_path_str(tcx.hir.local_def_id(node_id));
+    let node_path = item_path::with_forced_impl_filename_line(|| { // see notes on #41697 below
+        tcx.item_path_str(tcx.hir.local_def_id(node_id))
+    });
     filters.split("&")
            .any(|filter| {
                filter == "all" ||
@@ -76,6 +81,10 @@ pub fn dump_enabled<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            })
 }
 
+// #41697 -- we use `with_forced_impl_filename_line()` because
+// `item_path_str()` would otherwise trigger `type_of`, and this can
+// run while we are already attempting to evaluate `type_of`.
+
 fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                    pass_num: Option<(MirSuite, MirPassIndex)>,
                                    pass_name: &str,
diff --git a/src/test/run-pass/issue-41697.rs b/src/test/run-pass/issue-41697.rs
new file mode 100644 (file)
index 0000000..d59b6a1
--- /dev/null
@@ -0,0 +1,50 @@
+// 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.
+
+// compile-flags:-Zdump-mir=NEVER_MATCHED
+
+// Regression test for #41697. Using dump-mir was triggering
+// artificial cycles: during type-checking, we had to get the MIR for
+// the constant expressions in `[u8; 2]`, which in turn would trigger
+// an attempt to get the item-path, which in turn would request the
+// types of the impl, which would trigger a cycle. We supressed this
+// cycle now by forcing mir-dump to avoid asking for types of an impl.
+
+#![feature(rustc_attrs)]
+
+use std::sync::Arc;
+
+trait Foo {
+    fn get(&self) -> [u8; 2];
+}
+
+impl Foo for [u8; 2] {
+    fn get(&self) -> [u8; 2] {
+        *self
+    }
+}
+
+struct Bar<T: ?Sized>(T);
+
+fn unsize_fat_ptr<'a>(x: &'a Bar<Foo + Send + 'a>) -> &'a Bar<Foo + 'a> {
+    x
+}
+
+fn unsize_nested_fat_ptr(x: Arc<Foo + Send>) -> Arc<Foo> {
+    x
+}
+
+fn main() {
+    let x: Box<Bar<Foo + Send>> = Box::new(Bar([1,2]));
+    assert_eq!(unsize_fat_ptr(&*x).0.get(), [1, 2]);
+
+    let x: Arc<Foo + Send> = Arc::new([3, 4]);
+    assert_eq!(unsize_nested_fat_ptr(x).get(), [3, 4]);
+}