mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Auto merge of #66072 - Mark-Simulacrum:next-node-id, r=nikomatsakis
Move next node ID to Resolver This moves the `next_node_id` method(s) and related tracking information to the resolver. By doing so, we also remove the OneThread and Cell on next_node_id in Session in this move, which means that the new code is simpler and less "interesting" as it doesn't tie itself to a single thread. This required moving some of the pretty-printing logic around, but this was just copying the code without any semantic changes, so it's just a second commit instead of a separate PR; I can polish it up a bit more if desired.
This commit is contained in:
commit
86c28325ff
@ -3506,6 +3506,7 @@ dependencies = [
|
||||
"rustc_mir",
|
||||
"rustc_plugin",
|
||||
"rustc_plugin_impl",
|
||||
"rustc_resolve",
|
||||
"rustc_save_analysis",
|
||||
"rustc_target",
|
||||
"serialize",
|
||||
|
@ -183,6 +183,8 @@ pub trait Resolver {
|
||||
) -> (ast::Path, Res<NodeId>);
|
||||
|
||||
fn lint_buffer(&mut self) -> &mut lint::LintBuffer;
|
||||
|
||||
fn next_node_id(&mut self) -> NodeId;
|
||||
}
|
||||
|
||||
type NtToTokenstream = fn(&Nonterminal, &ParseSess, Span) -> TokenStream;
|
||||
@ -672,7 +674,8 @@ impl<'a> LoweringContext<'a> {
|
||||
}
|
||||
|
||||
fn next_id(&mut self) -> hir::HirId {
|
||||
self.lower_node_id(self.sess.next_node_id())
|
||||
let node_id = self.resolver.next_node_id();
|
||||
self.lower_node_id(node_id)
|
||||
}
|
||||
|
||||
fn lower_res(&mut self, res: Res<NodeId>) -> Res {
|
||||
@ -781,7 +784,7 @@ impl<'a> LoweringContext<'a> {
|
||||
hir_name: ParamName,
|
||||
parent_index: DefIndex,
|
||||
) -> hir::GenericParam {
|
||||
let node_id = self.sess.next_node_id();
|
||||
let node_id = self.resolver.next_node_id();
|
||||
|
||||
// Get the name we'll use to make the def-path. Note
|
||||
// that collisions are ok here and this shouldn't
|
||||
@ -1106,7 +1109,7 @@ impl<'a> LoweringContext<'a> {
|
||||
// Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by
|
||||
// constructing the HIR for `impl bounds...` and then lowering that.
|
||||
|
||||
let impl_trait_node_id = self.sess.next_node_id();
|
||||
let impl_trait_node_id = self.resolver.next_node_id();
|
||||
let parent_def_index = self.current_hir_id_owner.last().unwrap().0;
|
||||
self.resolver.definitions().create_def_with_parent(
|
||||
parent_def_index,
|
||||
@ -1117,9 +1120,10 @@ impl<'a> LoweringContext<'a> {
|
||||
);
|
||||
|
||||
self.with_dyn_type_scope(false, |this| {
|
||||
let node_id = this.resolver.next_node_id();
|
||||
let ty = this.lower_ty(
|
||||
&Ty {
|
||||
id: this.sess.next_node_id(),
|
||||
id: node_id,
|
||||
kind: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()),
|
||||
span: constraint.span,
|
||||
},
|
||||
@ -1586,7 +1590,7 @@ impl<'a> LoweringContext<'a> {
|
||||
name,
|
||||
}));
|
||||
|
||||
let def_node_id = self.context.sess.next_node_id();
|
||||
let def_node_id = self.context.resolver.next_node_id();
|
||||
let hir_id =
|
||||
self.context.lower_node_id_with_owner(def_node_id, self.opaque_ty_id);
|
||||
self.context.resolver.definitions().create_def_with_parent(
|
||||
@ -3234,7 +3238,7 @@ impl<'a> LoweringContext<'a> {
|
||||
Some(id) => (id, "`'_` cannot be used here", "`'_` is a reserved lifetime name"),
|
||||
|
||||
None => (
|
||||
self.sess.next_node_id(),
|
||||
self.resolver.next_node_id(),
|
||||
"`&` without an explicit lifetime name cannot be used here",
|
||||
"explicit lifetime name needed here",
|
||||
),
|
||||
@ -3271,7 +3275,7 @@ impl<'a> LoweringContext<'a> {
|
||||
span,
|
||||
"expected 'implicit elided lifetime not allowed' error",
|
||||
);
|
||||
let id = self.sess.next_node_id();
|
||||
let id = self.resolver.next_node_id();
|
||||
self.new_named_lifetime(id, span, hir::LifetimeName::Error)
|
||||
}
|
||||
// `PassThrough` is the normal case.
|
||||
|
@ -595,7 +595,7 @@ impl LoweringContext<'_> {
|
||||
};
|
||||
|
||||
// `::std::task::Poll::Ready(result) => break result`
|
||||
let loop_node_id = self.sess.next_node_id();
|
||||
let loop_node_id = self.resolver.next_node_id();
|
||||
let loop_hir_id = self.lower_node_id(loop_node_id);
|
||||
let ready_arm = {
|
||||
let x_ident = Ident::with_dummy_span(sym::result);
|
||||
|
@ -522,7 +522,7 @@ impl LoweringContext<'_> {
|
||||
let ident = *ident;
|
||||
let mut path = path.clone();
|
||||
for seg in &mut path.segments {
|
||||
seg.id = self.sess.next_node_id();
|
||||
seg.id = self.resolver.next_node_id();
|
||||
}
|
||||
let span = path.span;
|
||||
|
||||
@ -599,7 +599,7 @@ impl LoweringContext<'_> {
|
||||
|
||||
// Give the segments new node-ids since they are being cloned.
|
||||
for seg in &mut prefix.segments {
|
||||
seg.id = self.sess.next_node_id();
|
||||
seg.id = self.resolver.next_node_id();
|
||||
}
|
||||
|
||||
// Each `use` import is an item and thus are owners of the
|
||||
|
@ -1,10 +1,13 @@
|
||||
//! Contains infrastructure for configuring the compiler, including parsing
|
||||
//! command-line options.
|
||||
|
||||
// ignore-tidy-filelength
|
||||
|
||||
use crate::lint;
|
||||
use crate::middle::cstore;
|
||||
use crate::session::{early_error, early_warn, Session};
|
||||
use crate::session::search_paths::SearchPath;
|
||||
use crate::hir::map as hir_map;
|
||||
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
|
||||
@ -440,6 +443,8 @@ top_level_options!(
|
||||
// `true` if we're emitting JSON blobs about each artifact produced
|
||||
// by the compiler.
|
||||
json_artifact_notifications: bool [TRACKED],
|
||||
|
||||
pretty: Option<(PpMode, Option<UserIdentifiedItem>)> [UNTRACKED],
|
||||
}
|
||||
);
|
||||
|
||||
@ -621,6 +626,7 @@ impl Default for Options {
|
||||
remap_path_prefix: Vec::new(),
|
||||
edition: DEFAULT_EDITION,
|
||||
json_artifact_notifications: false,
|
||||
pretty: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2516,6 +2522,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
|
||||
let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
|
||||
|
||||
let pretty = parse_pretty(matches, &debugging_opts, error_format);
|
||||
|
||||
Options {
|
||||
crate_types,
|
||||
optimize: opt_level,
|
||||
@ -2546,6 +2554,73 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
|
||||
remap_path_prefix,
|
||||
edition,
|
||||
json_artifact_notifications,
|
||||
pretty,
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_pretty(
|
||||
matches: &getopts::Matches,
|
||||
debugging_opts: &DebuggingOptions,
|
||||
efmt: ErrorOutputType,
|
||||
) -> Option<(PpMode, Option<UserIdentifiedItem>)> {
|
||||
let pretty = if debugging_opts.unstable_options {
|
||||
matches.opt_default("pretty", "normal").map(|a| {
|
||||
// stable pretty-print variants only
|
||||
parse_pretty_inner(efmt, &a, false)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
return if pretty.is_none() {
|
||||
debugging_opts.unpretty.as_ref().map(|a| {
|
||||
// extended with unstable pretty-print variants
|
||||
parse_pretty_inner(efmt, &a, true)
|
||||
})
|
||||
} else {
|
||||
pretty
|
||||
};
|
||||
|
||||
fn parse_pretty_inner(
|
||||
efmt: ErrorOutputType,
|
||||
name: &str,
|
||||
extended: bool,
|
||||
) -> (PpMode, Option<UserIdentifiedItem>) {
|
||||
use PpMode::*;
|
||||
use PpSourceMode::*;
|
||||
let mut split = name.splitn(2, '=');
|
||||
let first = split.next().unwrap();
|
||||
let opt_second = split.next();
|
||||
let first = match (first, extended) {
|
||||
("normal", _) => PpmSource(PpmNormal),
|
||||
("identified", _) => PpmSource(PpmIdentified),
|
||||
("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
|
||||
("expanded", _) => PpmSource(PpmExpanded),
|
||||
("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
|
||||
("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
|
||||
("hir", true) => PpmHir(PpmNormal),
|
||||
("hir,identified", true) => PpmHir(PpmIdentified),
|
||||
("hir,typed", true) => PpmHir(PpmTyped),
|
||||
("hir-tree", true) => PpmHirTree(PpmNormal),
|
||||
("mir", true) => PpmMir,
|
||||
("mir-cfg", true) => PpmMirCFG,
|
||||
_ => {
|
||||
if extended {
|
||||
early_error(efmt, &format!("argument to `unpretty` must be one of `normal`, \
|
||||
`expanded`, `identified`, `expanded,identified`, \
|
||||
`expanded,hygiene`, `everybody_loops`, \
|
||||
`hir`, `hir,identified`, `hir,typed`, `hir-tree`, \
|
||||
`mir` or `mir-cfg`; got {}",
|
||||
name));
|
||||
} else {
|
||||
early_error(efmt, &format!("argument to `pretty` must be one of `normal`, \
|
||||
`expanded`, `identified`, or `expanded,identified`; got {}",
|
||||
name));
|
||||
}
|
||||
}
|
||||
};
|
||||
let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>().ok());
|
||||
(first, opt_second)
|
||||
}
|
||||
}
|
||||
|
||||
@ -2656,6 +2731,151 @@ impl fmt::Display for CrateType {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpSourceMode {
|
||||
PpmNormal,
|
||||
PpmEveryBodyLoops,
|
||||
PpmExpanded,
|
||||
PpmIdentified,
|
||||
PpmExpandedIdentified,
|
||||
PpmExpandedHygiene,
|
||||
PpmTyped,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpMode {
|
||||
PpmSource(PpSourceMode),
|
||||
PpmHir(PpSourceMode),
|
||||
PpmHirTree(PpSourceMode),
|
||||
PpmMir,
|
||||
PpmMirCFG,
|
||||
}
|
||||
|
||||
impl PpMode {
|
||||
pub fn needs_ast_map(&self, opt_uii: &Option<UserIdentifiedItem>) -> bool {
|
||||
use PpMode::*;
|
||||
use PpSourceMode::*;
|
||||
match *self {
|
||||
PpmSource(PpmNormal) |
|
||||
PpmSource(PpmEveryBodyLoops) |
|
||||
PpmSource(PpmIdentified) => opt_uii.is_some(),
|
||||
|
||||
PpmSource(PpmExpanded) |
|
||||
PpmSource(PpmExpandedIdentified) |
|
||||
PpmSource(PpmExpandedHygiene) |
|
||||
PpmHir(_) |
|
||||
PpmHirTree(_) |
|
||||
PpmMir |
|
||||
PpmMirCFG => true,
|
||||
PpmSource(PpmTyped) => panic!("invalid state"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn needs_analysis(&self) -> bool {
|
||||
use PpMode::*;
|
||||
match *self {
|
||||
PpmMir | PpmMirCFG => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UserIdentifiedItem {
|
||||
ItemViaNode(ast::NodeId),
|
||||
ItemViaPath(Vec<String>),
|
||||
}
|
||||
|
||||
impl FromStr for UserIdentifiedItem {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
|
||||
use UserIdentifiedItem::*;
|
||||
Ok(s.parse()
|
||||
.map(ast::NodeId::from_u32)
|
||||
.map(ItemViaNode)
|
||||
.unwrap_or_else(|_| ItemViaPath(s.split("::").map(|s| s.to_string()).collect())))
|
||||
}
|
||||
}
|
||||
|
||||
pub enum NodesMatchingUII<'a> {
|
||||
NodesMatchingDirect(std::option::IntoIter<ast::NodeId>),
|
||||
NodesMatchingSuffix(Box<dyn Iterator<Item = ast::NodeId> + 'a>),
|
||||
}
|
||||
|
||||
impl<'a> Iterator for NodesMatchingUII<'a> {
|
||||
type Item = ast::NodeId;
|
||||
|
||||
fn next(&mut self) -> Option<ast::NodeId> {
|
||||
use NodesMatchingUII::*;
|
||||
match self {
|
||||
&mut NodesMatchingDirect(ref mut iter) => iter.next(),
|
||||
&mut NodesMatchingSuffix(ref mut iter) => iter.next(),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
use NodesMatchingUII::*;
|
||||
match self {
|
||||
&NodesMatchingDirect(ref iter) => iter.size_hint(),
|
||||
&NodesMatchingSuffix(ref iter) => iter.size_hint(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UserIdentifiedItem {
|
||||
pub fn reconstructed_input(&self) -> String {
|
||||
use UserIdentifiedItem::*;
|
||||
match *self {
|
||||
ItemViaNode(node_id) => node_id.to_string(),
|
||||
ItemViaPath(ref parts) => parts.join("::"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn all_matching_node_ids<'a, 'hir>(&'a self,
|
||||
map: &'a hir_map::Map<'hir>)
|
||||
-> NodesMatchingUII<'a> {
|
||||
use UserIdentifiedItem::*;
|
||||
use NodesMatchingUII::*;
|
||||
match *self {
|
||||
ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()),
|
||||
ItemViaPath(ref parts) => {
|
||||
NodesMatchingSuffix(Box::new(map.nodes_matching_suffix(&parts)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_one_node_id(self,
|
||||
user_option: &str,
|
||||
sess: &Session,
|
||||
map: &hir_map::Map<'_>)
|
||||
-> ast::NodeId {
|
||||
let fail_because = |is_wrong_because| -> ast::NodeId {
|
||||
let message = format!("{} needs NodeId (int) or unique path suffix (b::c::d); got \
|
||||
{}, which {}",
|
||||
user_option,
|
||||
self.reconstructed_input(),
|
||||
is_wrong_because);
|
||||
sess.fatal(&message)
|
||||
};
|
||||
|
||||
let mut saw_node = ast::DUMMY_NODE_ID;
|
||||
let mut seen = 0;
|
||||
for node in self.all_matching_node_ids(map) {
|
||||
saw_node = node;
|
||||
seen += 1;
|
||||
if seen > 1 {
|
||||
fail_because("does not resolve uniquely");
|
||||
}
|
||||
}
|
||||
if seen == 0 {
|
||||
fail_because("does not resolve to any item");
|
||||
}
|
||||
|
||||
assert!(seen == 1);
|
||||
return saw_node;
|
||||
}
|
||||
}
|
||||
|
||||
/// Command-line arguments passed to the compiler have to be incorporated with
|
||||
/// the dependency tracking system for incremental compilation. This module
|
||||
/// provides some utilities to make this more convenient.
|
||||
|
@ -21,7 +21,6 @@ use errors::{DiagnosticBuilder, DiagnosticId, Applicability};
|
||||
use errors::emitter::{Emitter, EmitterWriter};
|
||||
use errors::emitter::HumanReadableErrorType;
|
||||
use errors::annotate_snippet_emitter_writer::{AnnotateSnippetEmitterWriter};
|
||||
use syntax::ast::{self, NodeId};
|
||||
use syntax::edition::Edition;
|
||||
use syntax::expand::allocator::AllocatorKind;
|
||||
use syntax::feature_gate::{self, AttributeType};
|
||||
@ -38,7 +37,7 @@ use rustc_data_structures::jobserver;
|
||||
use ::jobserver::Client;
|
||||
|
||||
use std;
|
||||
use std::cell::{self, Cell, RefCell};
|
||||
use std::cell::{self, RefCell};
|
||||
use std::env;
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
@ -127,8 +126,6 @@ pub struct Session {
|
||||
/// Data about code being compiled, gathered during compilation.
|
||||
pub code_stats: Lock<CodeStats>,
|
||||
|
||||
next_node_id: OneThread<Cell<ast::NodeId>>,
|
||||
|
||||
/// If `-zfuel=crate=n` is specified, `Some(crate)`.
|
||||
optimization_fuel_crate: Option<String>,
|
||||
|
||||
@ -355,21 +352,6 @@ impl Session {
|
||||
self.diagnostic().span_note_without_error(sp, msg)
|
||||
}
|
||||
|
||||
pub fn reserve_node_ids(&self, count: usize) -> ast::NodeId {
|
||||
let id = self.next_node_id.get();
|
||||
|
||||
match id.as_usize().checked_add(count) {
|
||||
Some(next) => {
|
||||
self.next_node_id.set(ast::NodeId::from_usize(next));
|
||||
}
|
||||
None => bug!("input too large; ran out of node-IDs!"),
|
||||
}
|
||||
|
||||
id
|
||||
}
|
||||
pub fn next_node_id(&self) -> NodeId {
|
||||
self.reserve_node_ids(1)
|
||||
}
|
||||
pub fn diagnostic(&self) -> &errors::Handler {
|
||||
&self.parse_sess.span_diagnostic
|
||||
}
|
||||
@ -1187,7 +1169,6 @@ fn build_session_(
|
||||
recursion_limit: Once::new(),
|
||||
type_length_limit: Once::new(),
|
||||
const_eval_stack_frame_limit: 100,
|
||||
next_node_id: OneThread::new(Cell::new(NodeId::from_u32(1))),
|
||||
allocator_kind: Once::new(),
|
||||
injected_panic_runtime: Once::new(),
|
||||
imported_macro_spans: OneThread::new(RefCell::new(FxHashMap::default())),
|
||||
|
@ -27,5 +27,6 @@ rustc_save_analysis = { path = "../librustc_save_analysis" }
|
||||
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
|
||||
rustc_interface = { path = "../librustc_interface" }
|
||||
rustc_serialize = { path = "../libserialize", package = "serialize" }
|
||||
rustc_resolve = { path = "../librustc_resolve" }
|
||||
syntax = { path = "../libsyntax" }
|
||||
syntax_pos = { path = "../libsyntax_pos" }
|
||||
|
@ -25,8 +25,6 @@ extern crate lazy_static;
|
||||
|
||||
pub extern crate rustc_plugin_impl as plugin;
|
||||
|
||||
use pretty::{PpMode, UserIdentifiedItem};
|
||||
|
||||
//use rustc_resolve as resolve;
|
||||
use rustc_save_analysis as save;
|
||||
use rustc_save_analysis::DumpHandler;
|
||||
@ -285,33 +283,29 @@ pub fn run_compiler(
|
||||
return sess.compile_status();
|
||||
}
|
||||
|
||||
let pretty_info = parse_pretty(sess, &matches);
|
||||
|
||||
compiler.parse()?;
|
||||
|
||||
if let Some((ppm, opt_uii)) = pretty_info {
|
||||
if let Some((ppm, opt_uii)) = &sess.opts.pretty {
|
||||
if ppm.needs_ast_map(&opt_uii) {
|
||||
pretty::visit_crate(sess, &mut compiler.parse()?.peek_mut(), ppm);
|
||||
compiler.global_ctxt()?.peek_mut().enter(|tcx| {
|
||||
let expanded_crate = compiler.expansion()?.take().0;
|
||||
pretty::print_after_hir_lowering(
|
||||
tcx,
|
||||
compiler.input(),
|
||||
&expanded_crate,
|
||||
ppm,
|
||||
*ppm,
|
||||
opt_uii.clone(),
|
||||
compiler.output_file().as_ref().map(|p| &**p),
|
||||
);
|
||||
Ok(())
|
||||
})?;
|
||||
} else {
|
||||
let mut krate = compiler.parse()?.take();
|
||||
pretty::visit_crate(sess, &mut krate, ppm);
|
||||
let krate = compiler.parse()?.take();
|
||||
pretty::print_after_parsing(
|
||||
sess,
|
||||
&compiler.input(),
|
||||
&krate,
|
||||
ppm,
|
||||
*ppm,
|
||||
compiler.output_file().as_ref().map(|p| &**p),
|
||||
);
|
||||
}
|
||||
@ -470,28 +464,6 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_pretty(sess: &Session,
|
||||
matches: &getopts::Matches)
|
||||
-> Option<(PpMode, Option<UserIdentifiedItem>)> {
|
||||
let pretty = if sess.opts.debugging_opts.unstable_options {
|
||||
matches.opt_default("pretty", "normal").map(|a| {
|
||||
// stable pretty-print variants only
|
||||
pretty::parse_pretty(sess, &a, false)
|
||||
})
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if pretty.is_none() {
|
||||
sess.opts.debugging_opts.unpretty.as_ref().map(|a| {
|
||||
// extended with unstable pretty-print variants
|
||||
pretty::parse_pretty(sess, &a, true)
|
||||
})
|
||||
} else {
|
||||
pretty
|
||||
}
|
||||
}
|
||||
|
||||
// Whether to stop or continue compilation.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum Compilation {
|
||||
|
@ -5,117 +5,27 @@ use rustc::hir::map as hir_map;
|
||||
use rustc::hir::print as pprust_hir;
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::Input;
|
||||
use rustc::session::config::{PpMode, PpSourceMode, UserIdentifiedItem, Input};
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::util::common::ErrorReported;
|
||||
use rustc_interface::util::ReplaceBodyWithLoop;
|
||||
use rustc_mir::util::{write_mir_pretty, write_mir_graphviz};
|
||||
|
||||
use syntax::ast;
|
||||
use syntax::mut_visit::MutVisitor;
|
||||
use syntax::print::{pprust};
|
||||
use syntax_pos::FileName;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::fs::File;
|
||||
use std::io::Write;
|
||||
use std::option;
|
||||
use std::path::Path;
|
||||
use std::str::FromStr;
|
||||
|
||||
pub use self::UserIdentifiedItem::*;
|
||||
pub use self::PpSourceMode::*;
|
||||
pub use self::PpMode::*;
|
||||
use self::NodesMatchingUII::*;
|
||||
use crate::abort_on_err;
|
||||
|
||||
use crate::source_name;
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpSourceMode {
|
||||
PpmNormal,
|
||||
PpmEveryBodyLoops,
|
||||
PpmExpanded,
|
||||
PpmIdentified,
|
||||
PpmExpandedIdentified,
|
||||
PpmExpandedHygiene,
|
||||
PpmTyped,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, PartialEq, Debug)]
|
||||
pub enum PpMode {
|
||||
PpmSource(PpSourceMode),
|
||||
PpmHir(PpSourceMode),
|
||||
PpmHirTree(PpSourceMode),
|
||||
PpmMir,
|
||||
PpmMirCFG,
|
||||
}
|
||||
|
||||
impl PpMode {
|
||||
pub fn needs_ast_map(&self, opt_uii: &Option<UserIdentifiedItem>) -> bool {
|
||||
match *self {
|
||||
PpmSource(PpmNormal) |
|
||||
PpmSource(PpmEveryBodyLoops) |
|
||||
PpmSource(PpmIdentified) => opt_uii.is_some(),
|
||||
|
||||
PpmSource(PpmExpanded) |
|
||||
PpmSource(PpmExpandedIdentified) |
|
||||
PpmSource(PpmExpandedHygiene) |
|
||||
PpmHir(_) |
|
||||
PpmHirTree(_) |
|
||||
PpmMir |
|
||||
PpmMirCFG => true,
|
||||
PpmSource(PpmTyped) => panic!("invalid state"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn needs_analysis(&self) -> bool {
|
||||
match *self {
|
||||
PpmMir | PpmMirCFG => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_pretty(sess: &Session,
|
||||
name: &str,
|
||||
extended: bool)
|
||||
-> (PpMode, Option<UserIdentifiedItem>) {
|
||||
let mut split = name.splitn(2, '=');
|
||||
let first = split.next().unwrap();
|
||||
let opt_second = split.next();
|
||||
let first = match (first, extended) {
|
||||
("normal", _) => PpmSource(PpmNormal),
|
||||
("identified", _) => PpmSource(PpmIdentified),
|
||||
("everybody_loops", true) => PpmSource(PpmEveryBodyLoops),
|
||||
("expanded", _) => PpmSource(PpmExpanded),
|
||||
("expanded,identified", _) => PpmSource(PpmExpandedIdentified),
|
||||
("expanded,hygiene", _) => PpmSource(PpmExpandedHygiene),
|
||||
("hir", true) => PpmHir(PpmNormal),
|
||||
("hir,identified", true) => PpmHir(PpmIdentified),
|
||||
("hir,typed", true) => PpmHir(PpmTyped),
|
||||
("hir-tree", true) => PpmHirTree(PpmNormal),
|
||||
("mir", true) => PpmMir,
|
||||
("mir-cfg", true) => PpmMirCFG,
|
||||
_ => {
|
||||
if extended {
|
||||
sess.fatal(&format!("argument to `unpretty` must be one of `normal`, \
|
||||
`expanded`, `identified`, `expanded,identified`, \
|
||||
`expanded,hygiene`, `everybody_loops`, \
|
||||
`hir`, `hir,identified`, `hir,typed`, `hir-tree`, \
|
||||
`mir` or `mir-cfg`; got {}",
|
||||
name));
|
||||
} else {
|
||||
sess.fatal(&format!("argument to `pretty` must be one of `normal`, `expanded`, \
|
||||
`identified`, or `expanded,identified`; got {}",
|
||||
name));
|
||||
}
|
||||
}
|
||||
};
|
||||
let opt_second = opt_second.and_then(|s| s.parse::<UserIdentifiedItem>().ok());
|
||||
(first, opt_second)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// This slightly awkward construction is to allow for each PpMode to
|
||||
@ -131,76 +41,74 @@ pub fn parse_pretty(sess: &Session,
|
||||
// (The `use_once_payload` is working around the current lack of once
|
||||
// functions in the compiler.)
|
||||
|
||||
impl PpSourceMode {
|
||||
/// Constructs a `PrinterSupport` object and passes it to `f`.
|
||||
fn call_with_pp_support<'tcx, A, F>(
|
||||
&self,
|
||||
sess: &'tcx Session,
|
||||
tcx: Option<TyCtxt<'tcx>>,
|
||||
f: F,
|
||||
) -> A
|
||||
where
|
||||
F: FnOnce(&dyn PrinterSupport) -> A,
|
||||
{
|
||||
match *self {
|
||||
PpmNormal | PpmEveryBodyLoops | PpmExpanded => {
|
||||
let annotation = NoAnn {
|
||||
sess,
|
||||
tcx,
|
||||
};
|
||||
f(&annotation)
|
||||
}
|
||||
|
||||
PpmIdentified | PpmExpandedIdentified => {
|
||||
let annotation = IdentifiedAnnotation {
|
||||
sess,
|
||||
tcx,
|
||||
};
|
||||
f(&annotation)
|
||||
}
|
||||
PpmExpandedHygiene => {
|
||||
let annotation = HygieneAnnotation {
|
||||
sess,
|
||||
};
|
||||
f(&annotation)
|
||||
}
|
||||
_ => panic!("Should use call_with_pp_support_hir"),
|
||||
/// Constructs a `PrinterSupport` object and passes it to `f`.
|
||||
fn call_with_pp_support<'tcx, A, F>(
|
||||
ppmode: &PpSourceMode,
|
||||
sess: &'tcx Session,
|
||||
tcx: Option<TyCtxt<'tcx>>,
|
||||
f: F,
|
||||
) -> A
|
||||
where
|
||||
F: FnOnce(&dyn PrinterSupport) -> A,
|
||||
{
|
||||
match *ppmode {
|
||||
PpmNormal | PpmEveryBodyLoops | PpmExpanded => {
|
||||
let annotation = NoAnn {
|
||||
sess,
|
||||
tcx,
|
||||
};
|
||||
f(&annotation)
|
||||
}
|
||||
|
||||
PpmIdentified | PpmExpandedIdentified => {
|
||||
let annotation = IdentifiedAnnotation {
|
||||
sess,
|
||||
tcx,
|
||||
};
|
||||
f(&annotation)
|
||||
}
|
||||
PpmExpandedHygiene => {
|
||||
let annotation = HygieneAnnotation {
|
||||
sess,
|
||||
};
|
||||
f(&annotation)
|
||||
}
|
||||
_ => panic!("Should use call_with_pp_support_hir"),
|
||||
}
|
||||
fn call_with_pp_support_hir<A, F>(&self, tcx: TyCtxt<'_>, f: F) -> A
|
||||
where
|
||||
F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A,
|
||||
{
|
||||
match *self {
|
||||
PpmNormal => {
|
||||
let annotation = NoAnn {
|
||||
sess: tcx.sess,
|
||||
tcx: Some(tcx),
|
||||
};
|
||||
f(&annotation, tcx.hir().forest.krate())
|
||||
}
|
||||
|
||||
PpmIdentified => {
|
||||
let annotation = IdentifiedAnnotation {
|
||||
sess: tcx.sess,
|
||||
tcx: Some(tcx),
|
||||
};
|
||||
f(&annotation, tcx.hir().forest.krate())
|
||||
}
|
||||
PpmTyped => {
|
||||
abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess);
|
||||
|
||||
let empty_tables = ty::TypeckTables::empty(None);
|
||||
let annotation = TypedAnnotation {
|
||||
tcx,
|
||||
tables: Cell::new(&empty_tables)
|
||||
};
|
||||
tcx.dep_graph.with_ignore(|| {
|
||||
f(&annotation, tcx.hir().forest.krate())
|
||||
})
|
||||
}
|
||||
_ => panic!("Should use call_with_pp_support"),
|
||||
}
|
||||
fn call_with_pp_support_hir<A, F>(ppmode: &PpSourceMode, tcx: TyCtxt<'_>, f: F) -> A
|
||||
where
|
||||
F: FnOnce(&dyn HirPrinterSupport<'_>, &hir::Crate) -> A,
|
||||
{
|
||||
match *ppmode {
|
||||
PpmNormal => {
|
||||
let annotation = NoAnn {
|
||||
sess: tcx.sess,
|
||||
tcx: Some(tcx),
|
||||
};
|
||||
f(&annotation, tcx.hir().forest.krate())
|
||||
}
|
||||
|
||||
PpmIdentified => {
|
||||
let annotation = IdentifiedAnnotation {
|
||||
sess: tcx.sess,
|
||||
tcx: Some(tcx),
|
||||
};
|
||||
f(&annotation, tcx.hir().forest.krate())
|
||||
}
|
||||
PpmTyped => {
|
||||
abort_on_err(tcx.analysis(LOCAL_CRATE), tcx.sess);
|
||||
|
||||
let empty_tables = ty::TypeckTables::empty(None);
|
||||
let annotation = TypedAnnotation {
|
||||
tcx,
|
||||
tables: Cell::new(&empty_tables)
|
||||
};
|
||||
tcx.dep_graph.with_ignore(|| {
|
||||
f(&annotation, tcx.hir().forest.krate())
|
||||
})
|
||||
}
|
||||
_ => panic!("Should use call_with_pp_support"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -482,102 +390,6 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum UserIdentifiedItem {
|
||||
ItemViaNode(ast::NodeId),
|
||||
ItemViaPath(Vec<String>),
|
||||
}
|
||||
|
||||
impl FromStr for UserIdentifiedItem {
|
||||
type Err = ();
|
||||
fn from_str(s: &str) -> Result<UserIdentifiedItem, ()> {
|
||||
Ok(s.parse()
|
||||
.map(ast::NodeId::from_u32)
|
||||
.map(ItemViaNode)
|
||||
.unwrap_or_else(|_| ItemViaPath(s.split("::").map(|s| s.to_string()).collect())))
|
||||
}
|
||||
}
|
||||
|
||||
enum NodesMatchingUII<'a> {
|
||||
NodesMatchingDirect(option::IntoIter<ast::NodeId>),
|
||||
NodesMatchingSuffix(Box<dyn Iterator<Item = ast::NodeId> + 'a>),
|
||||
}
|
||||
|
||||
impl<'a> Iterator for NodesMatchingUII<'a> {
|
||||
type Item = ast::NodeId;
|
||||
|
||||
fn next(&mut self) -> Option<ast::NodeId> {
|
||||
match self {
|
||||
&mut NodesMatchingDirect(ref mut iter) => iter.next(),
|
||||
&mut NodesMatchingSuffix(ref mut iter) => iter.next(),
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
match self {
|
||||
&NodesMatchingDirect(ref iter) => iter.size_hint(),
|
||||
&NodesMatchingSuffix(ref iter) => iter.size_hint(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl UserIdentifiedItem {
|
||||
fn reconstructed_input(&self) -> String {
|
||||
match *self {
|
||||
ItemViaNode(node_id) => node_id.to_string(),
|
||||
ItemViaPath(ref parts) => parts.join("::"),
|
||||
}
|
||||
}
|
||||
|
||||
fn all_matching_node_ids<'a, 'hir>(&'a self,
|
||||
map: &'a hir_map::Map<'hir>)
|
||||
-> NodesMatchingUII<'a> {
|
||||
match *self {
|
||||
ItemViaNode(node_id) => NodesMatchingDirect(Some(node_id).into_iter()),
|
||||
ItemViaPath(ref parts) => {
|
||||
NodesMatchingSuffix(Box::new(map.nodes_matching_suffix(&parts)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn to_one_node_id(self,
|
||||
user_option: &str,
|
||||
sess: &Session,
|
||||
map: &hir_map::Map<'_>)
|
||||
-> ast::NodeId {
|
||||
let fail_because = |is_wrong_because| -> ast::NodeId {
|
||||
let message = format!("{} needs NodeId (int) or unique path suffix (b::c::d); got \
|
||||
{}, which {}",
|
||||
user_option,
|
||||
self.reconstructed_input(),
|
||||
is_wrong_because);
|
||||
sess.fatal(&message)
|
||||
};
|
||||
|
||||
let mut saw_node = ast::DUMMY_NODE_ID;
|
||||
let mut seen = 0;
|
||||
for node in self.all_matching_node_ids(map) {
|
||||
saw_node = node;
|
||||
seen += 1;
|
||||
if seen > 1 {
|
||||
fail_because("does not resolve uniquely");
|
||||
}
|
||||
}
|
||||
if seen == 0 {
|
||||
fail_because("does not resolve to any item");
|
||||
}
|
||||
|
||||
assert!(seen == 1);
|
||||
return saw_node;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn visit_crate(sess: &Session, krate: &mut ast::Crate, ppm: PpMode) {
|
||||
if let PpmSource(PpmEveryBodyLoops) = ppm {
|
||||
ReplaceBodyWithLoop::new(sess).visit_crate(krate);
|
||||
}
|
||||
}
|
||||
|
||||
fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
|
||||
let src_name = source_name(input);
|
||||
let src = String::clone(&sess.source_map()
|
||||
@ -613,7 +425,7 @@ pub fn print_after_parsing(sess: &Session,
|
||||
if let PpmSource(s) = ppm {
|
||||
// Silently ignores an identified node.
|
||||
let out = &mut out;
|
||||
s.call_with_pp_support(sess, None, move |annotation| {
|
||||
call_with_pp_support(&s, sess, None, move |annotation| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
*out = pprust::print_crate(sess.source_map(),
|
||||
@ -658,7 +470,7 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
// Silently ignores an identified node.
|
||||
let out = &mut out;
|
||||
let src = src.clone();
|
||||
s.call_with_pp_support(tcx.sess, Some(tcx), move |annotation| {
|
||||
call_with_pp_support(&s, tcx.sess, Some(tcx), move |annotation| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
*out = pprust::print_crate(sess.source_map(),
|
||||
@ -674,7 +486,7 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
(PpmHir(s), None) => {
|
||||
let out = &mut out;
|
||||
let src = src.clone();
|
||||
s.call_with_pp_support_hir(tcx, move |annotation, krate| {
|
||||
call_with_pp_support_hir(&s, tcx, move |annotation, krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
*out = pprust_hir::print_crate(sess.source_map(),
|
||||
@ -688,7 +500,7 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
|
||||
(PpmHirTree(s), None) => {
|
||||
let out = &mut out;
|
||||
s.call_with_pp_support_hir(tcx, move |_annotation, krate| {
|
||||
call_with_pp_support_hir(&s, tcx, move |_annotation, krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
*out = format!("{:#?}", krate);
|
||||
});
|
||||
@ -697,7 +509,7 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
(PpmHir(s), Some(uii)) => {
|
||||
let out = &mut out;
|
||||
let src = src.clone();
|
||||
s.call_with_pp_support_hir(tcx, move |annotation, _| {
|
||||
call_with_pp_support_hir(&s, tcx, move |annotation, _| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
let hir_map = annotation.hir_map().expect("-Z unpretty missing HIR map");
|
||||
@ -722,7 +534,7 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
|
||||
(PpmHirTree(s), Some(uii)) => {
|
||||
let out = &mut out;
|
||||
s.call_with_pp_support_hir(tcx, move |_annotation, _krate| {
|
||||
call_with_pp_support_hir(&s, tcx, move |_annotation, _krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
for node_id in uii.all_matching_node_ids(tcx.hir()) {
|
||||
let hir_id = tcx.hir().node_to_hir_id(node_id);
|
||||
|
@ -16,6 +16,7 @@ use rustc::traits;
|
||||
use rustc::util::common::{time, ErrorReported};
|
||||
use rustc::session::Session;
|
||||
use rustc::session::config::{self, CrateType, Input, OutputFilenames, OutputType};
|
||||
use rustc::session::config::{PpMode, PpSourceMode};
|
||||
use rustc::session::search_paths::PathKind;
|
||||
use rustc_codegen_ssa::back::link::emit_metadata;
|
||||
use rustc_codegen_utils::codegen_backend::CodegenBackend;
|
||||
@ -394,8 +395,12 @@ fn configure_and_expand_inner<'a>(
|
||||
|
||||
// If we're actually rustdoc then there's no need to actually compile
|
||||
// anything, so switch everything to just looping
|
||||
if sess.opts.actually_rustdoc {
|
||||
util::ReplaceBodyWithLoop::new(sess).visit_crate(&mut krate);
|
||||
let mut should_loop = sess.opts.actually_rustdoc;
|
||||
if let Some((PpMode::PpmSource(PpSourceMode::PpmEveryBodyLoops), _)) = sess.opts.pretty {
|
||||
should_loop |= true;
|
||||
}
|
||||
if should_loop {
|
||||
util::ReplaceBodyWithLoop::new(&mut resolver).visit_crate(&mut krate);
|
||||
}
|
||||
|
||||
let has_proc_macro_decls = time(sess, "AST validation", || {
|
||||
|
@ -18,7 +18,7 @@ use rustc_mir;
|
||||
use rustc_passes;
|
||||
use rustc_plugin;
|
||||
use rustc_privacy;
|
||||
use rustc_resolve;
|
||||
use rustc_resolve::{self, Resolver};
|
||||
use rustc_typeck;
|
||||
use std::env;
|
||||
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
|
||||
@ -715,18 +715,18 @@ pub fn build_output_filenames(
|
||||
// ambitious form of the closed RFC #1637. See also [#34511].
|
||||
//
|
||||
// [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401
|
||||
pub struct ReplaceBodyWithLoop<'a> {
|
||||
pub struct ReplaceBodyWithLoop<'a, 'b> {
|
||||
within_static_or_const: bool,
|
||||
nested_blocks: Option<Vec<ast::Block>>,
|
||||
sess: &'a Session,
|
||||
resolver: &'a mut Resolver<'b>,
|
||||
}
|
||||
|
||||
impl<'a> ReplaceBodyWithLoop<'a> {
|
||||
pub fn new(sess: &'a Session) -> ReplaceBodyWithLoop<'a> {
|
||||
impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
|
||||
pub fn new(resolver: &'a mut Resolver<'b>) -> ReplaceBodyWithLoop<'a, 'b> {
|
||||
ReplaceBodyWithLoop {
|
||||
within_static_or_const: false,
|
||||
nested_blocks: None,
|
||||
sess
|
||||
resolver,
|
||||
}
|
||||
}
|
||||
|
||||
@ -788,11 +788,12 @@ impl<'a> ReplaceBodyWithLoop<'a> {
|
||||
}
|
||||
|
||||
fn is_sig_const(sig: &ast::FnSig) -> bool {
|
||||
sig.header.constness.node == ast::Constness::Const || Self::should_ignore_fn(&sig.decl)
|
||||
sig.header.constness.node == ast::Constness::Const ||
|
||||
ReplaceBodyWithLoop::should_ignore_fn(&sig.decl)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
|
||||
impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> {
|
||||
fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
|
||||
let is_const = match i {
|
||||
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
|
||||
@ -827,40 +828,40 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
|
||||
fn visit_block(&mut self, b: &mut P<ast::Block>) {
|
||||
fn stmt_to_block(rules: ast::BlockCheckMode,
|
||||
s: Option<ast::Stmt>,
|
||||
sess: &Session) -> ast::Block {
|
||||
resolver: &mut Resolver<'_>) -> ast::Block {
|
||||
ast::Block {
|
||||
stmts: s.into_iter().collect(),
|
||||
rules,
|
||||
id: sess.next_node_id(),
|
||||
id: resolver.next_node_id(),
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
||||
fn block_to_stmt(b: ast::Block, sess: &Session) -> ast::Stmt {
|
||||
fn block_to_stmt(b: ast::Block, resolver: &mut Resolver<'_>) -> ast::Stmt {
|
||||
let expr = P(ast::Expr {
|
||||
id: sess.next_node_id(),
|
||||
id: resolver.next_node_id(),
|
||||
kind: ast::ExprKind::Block(P(b), None),
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
attrs: ThinVec::new(),
|
||||
});
|
||||
|
||||
ast::Stmt {
|
||||
id: sess.next_node_id(),
|
||||
id: resolver.next_node_id(),
|
||||
kind: ast::StmtKind::Expr(expr),
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
}
|
||||
}
|
||||
|
||||
let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.sess);
|
||||
let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.resolver);
|
||||
let loop_expr = P(ast::Expr {
|
||||
kind: ast::ExprKind::Loop(P(empty_block), None),
|
||||
id: self.sess.next_node_id(),
|
||||
id: self.resolver.next_node_id(),
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
attrs: ThinVec::new(),
|
||||
});
|
||||
|
||||
let loop_stmt = ast::Stmt {
|
||||
id: self.sess.next_node_id(),
|
||||
id: self.resolver.next_node_id(),
|
||||
span: syntax_pos::DUMMY_SP,
|
||||
kind: ast::StmtKind::Expr(loop_expr),
|
||||
};
|
||||
@ -878,7 +879,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
|
||||
// we put a Some in there earlier with that replace(), so this is valid
|
||||
let new_blocks = self.nested_blocks.take().unwrap();
|
||||
self.nested_blocks = old_blocks;
|
||||
stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, &self.sess)));
|
||||
stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, self.resolver)));
|
||||
}
|
||||
|
||||
let mut new_block = ast::Block {
|
||||
@ -892,7 +893,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
|
||||
old_blocks.push(new_block);
|
||||
}
|
||||
|
||||
stmt_to_block(b.rules, Some(loop_stmt), self.sess)
|
||||
stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver)
|
||||
} else {
|
||||
//push `loop {}` onto the end of our fresh block and yield that
|
||||
new_block.stmts.push(loop_stmt);
|
||||
|
@ -449,7 +449,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
name: kw::PathRoot,
|
||||
span: source.ident.span,
|
||||
},
|
||||
id: Some(self.r.session.next_node_id()),
|
||||
id: Some(self.r.next_node_id()),
|
||||
});
|
||||
source.ident.name = crate_name;
|
||||
}
|
||||
|
@ -961,6 +961,8 @@ pub struct Resolver<'a> {
|
||||
variant_vis: DefIdMap<ty::Visibility>,
|
||||
|
||||
lint_buffer: lint::LintBuffer,
|
||||
|
||||
next_node_id: NodeId,
|
||||
}
|
||||
|
||||
/// Nothing really interesting here; it just provides memory for the rest of the crate.
|
||||
@ -1078,6 +1080,10 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> {
|
||||
fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
|
||||
&mut self.lint_buffer
|
||||
}
|
||||
|
||||
fn next_node_id(&mut self) -> NodeId {
|
||||
self.next_node_id()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Resolver<'a> {
|
||||
@ -1226,9 +1232,18 @@ impl<'a> Resolver<'a> {
|
||||
.collect(),
|
||||
variant_vis: Default::default(),
|
||||
lint_buffer: lint::LintBuffer::default(),
|
||||
next_node_id: NodeId::from_u32(1),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn next_node_id(&mut self) -> NodeId {
|
||||
let next = self.next_node_id.as_usize()
|
||||
.checked_add(1)
|
||||
.expect("input too large; ran out of NodeIds");
|
||||
self.next_node_id = ast::NodeId::from_usize(next);
|
||||
self.next_node_id
|
||||
}
|
||||
|
||||
pub fn lint_buffer(&mut self) -> &mut lint::LintBuffer {
|
||||
&mut self.lint_buffer
|
||||
}
|
||||
@ -2827,9 +2842,9 @@ impl<'a> Resolver<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
fn new_ast_path_segment(&self, ident: Ident) -> ast::PathSegment {
|
||||
fn new_ast_path_segment(&mut self, ident: Ident) -> ast::PathSegment {
|
||||
let mut seg = ast::PathSegment::from_ident(ident);
|
||||
seg.id = self.session.next_node_id();
|
||||
seg.id = self.next_node_id();
|
||||
seg
|
||||
}
|
||||
|
||||
|
@ -95,7 +95,7 @@ fn fast_print_path(path: &ast::Path) -> Symbol {
|
||||
|
||||
impl<'a> base::Resolver for Resolver<'a> {
|
||||
fn next_node_id(&mut self) -> NodeId {
|
||||
self.session.next_node_id()
|
||||
self.next_node_id()
|
||||
}
|
||||
|
||||
fn resolve_dollar_crates(&mut self) {
|
||||
|
Loading…
Reference in New Issue
Block a user