-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix a few errant Krate
edges
#35960
Merged
Merged
fix a few errant Krate
edges
#35960
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
5415b34
write to inherent_impls during the visitor
nikomatsakis c6363b8
ignore dep-graph when loading inlined HIR
nikomatsakis 753590f
add a debugging mechanism to forbid edges
nikomatsakis 2a84449
allow testing DepNode::Krate edges directly
nikomatsakis 4c2f3ff
remove the "misc-items" from meta-data
nikomatsakis 2f91ba0
implement a debugging "shadow graph"
nikomatsakis fe6557e
expanding a def-id is not a read
nikomatsakis 07df812
kill the forbidden code
nikomatsakis 2446e25
kill extra `use`
nikomatsakis dadce25
always print def-path in Debug impl for DefId
nikomatsakis c2ffa2f
pacify the mercilous tidy
nikomatsakis 9ca5786
check stack discipline of tasks
nikomatsakis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ mod edges; | |
mod graph; | ||
mod query; | ||
mod raii; | ||
mod shadow; | ||
mod thread; | ||
mod visit; | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,3 +47,4 @@ impl<'graph> Drop for IgnoreTask<'graph> { | |
self.data.enqueue(DepMessage::PopIgnore); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
// Copyright 2012-2015 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. | ||
|
||
//! The "Shadow Graph" is maintained on the main thread and which | ||
//! tracks each message relating to the dep-graph and applies some | ||
//! sanity checks as they go by. If an error results, it means you get | ||
//! a nice stack-trace telling you precisely what caused the error. | ||
//! | ||
//! NOTE: This is a debugging facility which can potentially have non-trivial | ||
//! runtime impact. Therefore, it is largely compiled out if | ||
//! debug-assertions are not enabled. | ||
//! | ||
//! The basic sanity check, enabled if you have debug assertions | ||
//! enabled, is that there is always a task (or ignore) on the stack | ||
//! when you do read/write, and that the tasks are pushed/popped | ||
//! according to a proper stack discipline. | ||
//! | ||
//! Optionally, if you specify RUST_FORBID_DEP_GRAPH_EDGE, you can | ||
//! specify an edge filter to be applied to each edge as it is | ||
//! created. See `./README.md` for details. | ||
|
||
use hir::def_id::DefId; | ||
use std::cell::{BorrowState, RefCell}; | ||
use std::env; | ||
|
||
use super::DepNode; | ||
use super::thread::DepMessage; | ||
use super::debug::EdgeFilter; | ||
|
||
pub struct ShadowGraph { | ||
// if you push None onto the stack, that corresponds to an Ignore | ||
stack: RefCell<Vec<Option<DepNode<DefId>>>>, | ||
forbidden_edge: Option<EdgeFilter>, | ||
} | ||
|
||
const ENABLED: bool = cfg!(debug_assertions); | ||
|
||
impl ShadowGraph { | ||
pub fn new() -> Self { | ||
let forbidden_edge = if !ENABLED { | ||
None | ||
} else { | ||
match env::var("RUST_FORBID_DEP_GRAPH_EDGE") { | ||
Ok(s) => { | ||
match EdgeFilter::new(&s) { | ||
Ok(f) => Some(f), | ||
Err(err) => bug!("RUST_FORBID_DEP_GRAPH_EDGE invalid: {}", err), | ||
} | ||
} | ||
Err(_) => None, | ||
} | ||
}; | ||
|
||
ShadowGraph { | ||
stack: RefCell::new(vec![]), | ||
forbidden_edge: forbidden_edge, | ||
} | ||
} | ||
|
||
pub fn enqueue(&self, message: &DepMessage) { | ||
if ENABLED { | ||
match self.stack.borrow_state() { | ||
BorrowState::Unused => {} | ||
_ => { | ||
// When we apply edge filters, that invokes the | ||
// Debug trait on DefIds, which in turn reads from | ||
// various bits of state and creates reads! Ignore | ||
// those recursive reads. | ||
return; | ||
} | ||
} | ||
|
||
let mut stack = self.stack.borrow_mut(); | ||
match *message { | ||
DepMessage::Read(ref n) => self.check_edge(Some(Some(n)), top(&stack)), | ||
DepMessage::Write(ref n) => self.check_edge(top(&stack), Some(Some(n))), | ||
DepMessage::PushTask(ref n) => stack.push(Some(n.clone())), | ||
DepMessage::PushIgnore => stack.push(None), | ||
DepMessage::PopTask(ref n) => { | ||
match stack.pop() { | ||
Some(Some(m)) => { | ||
if *n != m { | ||
bug!("stack mismatch: found {:?} expected {:?}", m, n) | ||
} | ||
} | ||
Some(None) => bug!("stack mismatch: found Ignore expected {:?}", n), | ||
None => bug!("stack mismatch: found empty stack, expected {:?}", n), | ||
} | ||
} | ||
DepMessage::PopIgnore => { | ||
match stack.pop() { | ||
Some(Some(m)) => bug!("stack mismatch: found {:?} expected ignore", m), | ||
Some(None) => (), | ||
None => bug!("stack mismatch: found empty stack, expected ignore"), | ||
} | ||
} | ||
DepMessage::Query => (), | ||
} | ||
} | ||
} | ||
|
||
fn check_edge(&self, | ||
source: Option<Option<&DepNode<DefId>>>, | ||
target: Option<Option<&DepNode<DefId>>>) { | ||
assert!(ENABLED); | ||
match (source, target) { | ||
// cannot happen, one side is always Some(Some(_)) | ||
(None, None) => unreachable!(), | ||
|
||
// nothing on top of the stack | ||
(None, Some(n)) | (Some(n), None) => bug!("read/write of {:?} but no current task", n), | ||
|
||
// this corresponds to an Ignore being top of the stack | ||
(Some(None), _) | (_, Some(None)) => (), | ||
|
||
// a task is on top of the stack | ||
(Some(Some(source)), Some(Some(target))) => { | ||
if let Some(ref forbidden_edge) = self.forbidden_edge { | ||
if forbidden_edge.test(source, target) { | ||
bug!("forbidden edge {:?} -> {:?} created", source, target) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Do a little juggling: we get back a reference to an option at the | ||
// top of the stack, convert it to an optional reference. | ||
fn top<'s>(stack: &'s Vec<Option<DepNode<DefId>>>) -> Option<Option<&'s DepNode<DefId>>> { | ||
stack.last() | ||
.map(|n: &'s Option<DepNode<DefId>>| -> Option<&'s DepNode<DefId>> { | ||
// (*) | ||
// (*) type annotation just there to clarify what would | ||
// otherwise be some *really* obscure code | ||
n.as_ref() | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -927,6 +927,8 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, | |
ii: InlinedItem, | ||
fold_ops: F) | ||
-> &'ast InlinedItem { | ||
let _ignore = map.forest.dep_graph.in_ignore(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would either add a comment here why this is needed, or just use |
||
|
||
let mut fld = IdAndSpanUpdater::new(fold_ops); | ||
let ii = match ii { | ||
II::Item(d, i) => II::Item(fld.fold_ops.new_def_id(d), | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice!
:)