Skip to content

Move next node ID to Resolver #66072

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

Merged
merged 3 commits into from
Nov 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3506,6 +3506,7 @@ dependencies = [
"rustc_mir",
"rustc_plugin",
"rustc_plugin_impl",
"rustc_resolve",
"rustc_save_analysis",
"rustc_target",
"serialize",
Expand Down
18 changes: 11 additions & 7 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand All @@ -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,
},
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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",
),
Expand Down Expand Up @@ -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();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we add a method next_node_id on LoweringContext that just delegates to self.resolver so that the diff becomes smaller in case we want to move it again some time?

self.new_named_lifetime(id, span, hir::LifetimeName::Error)
}
// `PassThrough` is the normal case.
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/hir/lowering/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/hir/lowering/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down
220 changes: 220 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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],
}
);

Expand Down Expand Up @@ -621,6 +626,7 @@ impl Default for Options {
remap_path_prefix: Vec::new(),
edition: DEFAULT_EDITION,
json_artifact_notifications: false,
pretty: None,
}
}
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -2546,6 +2554,73 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
remap_path_prefix,
edition,
json_artifact_notifications,
pretty,
}
}

fn parse_pretty(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aw :( -- Ideally we should move stuff out of librustc instead of the other direction... perhaps we can move most of this file out of librustc...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's fine to do so but it's also a pretty involved change (perhaps we want to create a librustc_pretty or something) -- I don't think it should be done in this PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea; didn't mean in this PR. :)

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)
}
}

Expand Down Expand Up @@ -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.
Expand Down
Loading