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).
This commit is contained in:
parent
222971f7d2
commit
cadf187347
2 changed files with 61 additions and 2 deletions
|
@ -13,6 +13,7 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::mir::transform::{MirSuite, MirPassIndex, MirSource};
|
use rustc::mir::transform::{MirSuite, MirPassIndex, MirSource};
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
|
use rustc::ty::item_path;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::indexed_vec::{Idx};
|
use rustc_data_structures::indexed_vec::{Idx};
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
@ -48,7 +49,9 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
return;
|
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,
|
dump_matched_mir_node(tcx, pass_num, pass_name, &node_path,
|
||||||
disambiguator, source, mir);
|
disambiguator, source, mir);
|
||||||
for (index, promoted_mir) in mir.promoted.iter_enumerated() {
|
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,
|
Some(ref filters) => filters,
|
||||||
};
|
};
|
||||||
let node_id = source.item_id();
|
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("&")
|
filters.split("&")
|
||||||
.any(|filter| {
|
.any(|filter| {
|
||||||
filter == "all" ||
|
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>,
|
fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
pass_num: Option<(MirSuite, MirPassIndex)>,
|
pass_num: Option<(MirSuite, MirPassIndex)>,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
|
|
50
src/test/run-pass/issue-41697.rs
Normal file
50
src/test/run-pass/issue-41697.rs
Normal file
|
@ -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]);
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue