diff --git a/Cargo.lock b/Cargo.lock index 8bf6198913530..f1fa91362b1ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3668,6 +3668,7 @@ dependencies = [ "rustc_errors", "rustc_feature", "rustc_hir", + "rustc_hir_pretty", "rustc_interface", "rustc_lint", "rustc_metadata", @@ -3742,9 +3743,7 @@ dependencies = [ "lazy_static 1.4.0", "log", "rustc_ast", - "rustc_ast_pretty", "rustc_data_structures", - "rustc_errors", "rustc_index", "rustc_macros", "rustc_span", @@ -3753,6 +3752,18 @@ dependencies = [ "smallvec 1.0.0", ] +[[package]] +name = "rustc_hir_pretty" +version = "0.0.0" +dependencies = [ + "rustc_ast", + "rustc_ast_pretty", + "rustc_data_structures", + "rustc_hir", + "rustc_span", + "rustc_target", +] + [[package]] name = "rustc_incremental" version = "0.0.0" @@ -3903,6 +3914,7 @@ dependencies = [ "rustc_errors", "rustc_expand", "rustc_hir", + "rustc_hir_pretty", "rustc_index", "rustc_session", "rustc_span", @@ -4087,6 +4099,7 @@ dependencies = [ "rustc_ast_pretty", "rustc_data_structures", "rustc_hir", + "rustc_hir_pretty", "rustc_parse", "rustc_session", "rustc_span", diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 6290f5bb9b418..bc42ac1f0d7aa 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -10,7 +10,6 @@ use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, Definitions}; use rustc_hir::intravisit; use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_hir::print::Nested; use rustc_hir::*; use rustc_index::vec::IndexVec; use rustc_span::hygiene::MacroKind; @@ -890,20 +889,18 @@ impl<'hir> Map<'hir> { } } + /// Get a representation of this `id` for debugging purposes. + /// NOTE: Do NOT use this in diagnostics! pub fn node_to_string(&self, id: HirId) -> String { - hir_id_to_string(self, id, true) - } - - pub fn hir_to_user_string(&self, id: HirId) -> String { - hir_id_to_string(self, id, false) - } - - pub fn hir_to_pretty_string(&self, id: HirId) -> String { - print::to_string(self, |s| s.print_node(self.get(id))) + hir_id_to_string(self, id) } } impl<'hir> intravisit::Map<'hir> for Map<'hir> { + fn find(&self, hir_id: HirId) -> Option> { + self.find(hir_id) + } + fn body(&self, id: BodyId) -> &'hir Body<'hir> { self.body(id) } @@ -982,23 +979,8 @@ pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, cnum: CrateNum) -> &'tcx Indexe tcx.arena.alloc(IndexedHir { crate_hash, map }) } -/// Identical to the `PpAnn` implementation for `hir::Crate`, -/// except it avoids creating a dependency on the whole crate. -impl<'hir> print::PpAnn for Map<'hir> { - fn nested(&self, state: &mut print::State<'_>, nested: print::Nested) { - match nested { - Nested::Item(id) => state.print_item(self.expect_item(id.id)), - Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)), - Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)), - Nested::Body(id) => state.print_expr(&self.body(id).value), - Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat), - } - } -} - -fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { +fn hir_id_to_string(map: &Map<'_>, id: HirId) -> String { let id_str = format!(" (hir_id={})", id); - let id_str = if include_id { &id_str[..] } else { "" }; let path_str = || { // This functionality is used for debugging, try to use `TyCtxt` to get @@ -1019,6 +1001,9 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { }) }; + let span_str = || map.tcx.sess.source_map().span_to_snippet(map.span(id)).unwrap_or_default(); + let node_str = |prefix| format!("{} {}{}", prefix, span_str(), id_str); + match map.find(id) { Some(Node::Item(item)) => { let item_str = match item.kind { @@ -1069,22 +1054,20 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { Some(Node::Field(ref field)) => { format!("field {} in {}{}", field.ident, path_str(), id_str) } - Some(Node::AnonConst(_)) => format!("const {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Expr(_)) => format!("expr {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Stmt(_)) => format!("stmt {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::PathSegment(_)) => { - format!("path segment {}{}", map.hir_to_pretty_string(id), id_str) - } - Some(Node::Ty(_)) => format!("type {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::TraitRef(_)) => format!("trait_ref {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Binding(_)) => format!("local {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Pat(_)) => format!("pat {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Param(_)) => format!("param {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Arm(_)) => format!("arm {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Block(_)) => format!("block {}{}", map.hir_to_pretty_string(id), id_str), - Some(Node::Local(_)) => format!("local {}{}", map.hir_to_pretty_string(id), id_str), + Some(Node::AnonConst(_)) => node_str("const"), + Some(Node::Expr(_)) => node_str("expr"), + Some(Node::Stmt(_)) => node_str("stmt"), + Some(Node::PathSegment(_)) => node_str("path segment"), + Some(Node::Ty(_)) => node_str("type"), + Some(Node::TraitRef(_)) => node_str("trait ref"), + Some(Node::Binding(_)) => node_str("local"), + Some(Node::Pat(_)) => node_str("pat"), + Some(Node::Param(_)) => node_str("param"), + Some(Node::Arm(_)) => node_str("arm"), + Some(Node::Block(_)) => node_str("block"), + Some(Node::Local(_)) => node_str("local"), Some(Node::Ctor(..)) => format!("ctor {}{}", path_str(), id_str), - Some(Node::Lifetime(_)) => format!("lifetime {}{}", map.hir_to_pretty_string(id), id_str), + Some(Node::Lifetime(_)) => node_str("lifetime"), Some(Node::GenericParam(ref param)) => format!("generic_param {:?}{}", param, id_str), Some(Node::Visibility(ref vis)) => format!("visibility {:?}{}", vis, id_str), Some(Node::MacroDef(_)) => format!("macro {}{}", path_str(), id_str), diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml index aec10ee5ef537..3ca39b24c5276 100644 --- a/src/librustc_driver/Cargo.toml +++ b/src/librustc_driver/Cargo.toml @@ -21,6 +21,7 @@ rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_feature = { path = "../librustc_feature" } rustc_hir = { path = "../librustc_hir" } +rustc_hir_pretty = { path = "../librustc_hir_pretty" } rustc_metadata = { path = "../librustc_metadata" } rustc_mir = { path = "../librustc_mir" } rustc_parse = { path = "../librustc_parse" } diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 1e5cc55a82853..a57a70e6b8ca7 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -7,7 +7,7 @@ use rustc_ast::ast; use rustc_ast_pretty::pprust; use rustc_hir as hir; use rustc_hir::def_id::LOCAL_CRATE; -use rustc_hir::print as pprust_hir; +use rustc_hir_pretty as pprust_hir; use rustc_mir::util::{write_mir_graphviz, write_mir_pretty}; use rustc_session::config::{Input, PpMode, PpSourceMode}; use rustc_session::Session; @@ -155,7 +155,7 @@ impl<'hir> pprust::PpAnn for NoAnn<'hir> {} impl<'hir> pprust_hir::PpAnn for NoAnn<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(tcx) = self.tcx { - pprust_hir::PpAnn::nested(&tcx.hir(), state, nested) + pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) } } } @@ -228,7 +228,7 @@ impl<'hir> HirPrinterSupport<'hir> for IdentifiedAnnotation<'hir> { impl<'hir> pprust_hir::PpAnn for IdentifiedAnnotation<'hir> { fn nested(&self, state: &mut pprust_hir::State<'_>, nested: pprust_hir::Nested) { if let Some(ref tcx) = self.tcx { - pprust_hir::PpAnn::nested(&tcx.hir(), state, nested) + pprust_hir::PpAnn::nested(&(&tcx.hir() as &dyn hir::intravisit::Map<'_>), state, nested) } } fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { @@ -334,7 +334,8 @@ impl<'a, 'tcx> pprust_hir::PpAnn for TypedAnnotation<'a, 'tcx> { if let pprust_hir::Nested::Body(id) = nested { self.tables.set(self.tcx.body_tables(id)); } - pprust_hir::PpAnn::nested(&self.tcx.hir(), state, nested); + let pp_ann = &(&self.tcx.hir() as &dyn hir::intravisit::Map<'_>); + pprust_hir::PpAnn::nested(pp_ann, state, nested); self.tables.set(old_tables); } fn pre(&self, s: &mut pprust_hir::State<'_>, node: pprust_hir::AnnNode<'_>) { diff --git a/src/librustc_hir/Cargo.toml b/src/librustc_hir/Cargo.toml index b3682ea5a807c..811440fdeb987 100644 --- a/src/librustc_hir/Cargo.toml +++ b/src/librustc_hir/Cargo.toml @@ -10,13 +10,11 @@ path = "lib.rs" doctest = false [dependencies] -rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_target = { path = "../librustc_target" } rustc_macros = { path = "../librustc_macros" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_index = { path = "../librustc_index" } rustc_span = { path = "../librustc_span" } -rustc_errors = { path = "../librustc_errors" } rustc_serialize = { path = "../libserialize", package = "serialize" } rustc_ast = { path = "../librustc_ast" } lazy_static = "1" diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index bb864edc99969..2054759933f3c 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2,11 +2,6 @@ use crate::def::{DefKind, Namespace, Res}; use crate::def_id::DefId; crate use crate::hir_id::HirId; use crate::itemlikevisit; -use crate::print; - -crate use BlockCheckMode::*; -crate use FnRetTy::*; -crate use UnsafeSource::*; use rustc_ast::ast::{self, AsmDialect, CrateSugar, Ident, Name}; use rustc_ast::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy}; @@ -16,7 +11,6 @@ use rustc_ast::node_id::NodeMap; use rustc_ast::util::parser::ExprPrecedence; use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::sync::{par_for_each_in, Send, Sync}; -use rustc_errors::FatalError; use rustc_macros::HashStable_Generic; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::{kw, sym, Symbol}; @@ -169,12 +163,7 @@ impl fmt::Display for Lifetime { impl fmt::Debug for Lifetime { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "lifetime({}: {})", - self.hir_id, - print::to_string(print::NO_ANN, |s| s.print_lifetime(self)) - ) + write!(f, "lifetime({}: {})", self.hir_id, self.name.ident()) } } @@ -191,7 +180,7 @@ impl Lifetime { /// A `Path` is essentially Rust's notion of a name; for instance, /// `std::cmp::PartialEq`. It's represented as a sequence of identifiers, /// along with a bunch of supporting information. -#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub struct Path<'hir> { pub span: Span, /// The resolution for the path. @@ -206,18 +195,6 @@ impl Path<'_> { } } -impl fmt::Debug for Path<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "path({})", self) - } -} - -impl fmt::Display for Path<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "{}", print::to_string(print::NO_ANN, |s| s.print_path(self, false))) - } -} - /// A segment of a path: an identifier, an optional lifetime, and a set of /// types. #[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] @@ -388,9 +365,9 @@ pub enum GenericBound<'hir> { } impl GenericBound<'_> { - pub fn trait_def_id(&self) -> Option { + pub fn trait_ref(&self) -> Option<&TraitRef<'_>> { match self { - GenericBound::Trait(data, _) => Some(data.trait_ref.trait_def_id()), + GenericBound::Trait(data, _) => Some(&data.trait_ref), _ => None, } } @@ -758,7 +735,7 @@ pub struct Block<'hir> { pub targeted_by_break: bool, } -#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)] +#[derive(Debug, RustcEncodable, RustcDecodable, HashStable_Generic)] pub struct Pat<'hir> { #[stable_hasher(ignore)] pub hir_id: HirId, @@ -766,17 +743,6 @@ pub struct Pat<'hir> { pub span: Span, } -impl fmt::Debug for Pat<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "pat({}: {})", - self.hir_id, - print::to_string(print::NO_ANN, |s| s.print_pat(self)) - ) - } -} - impl Pat<'_> { // FIXME(#19596) this is a workaround, but there should be a better way fn walk_short_(&self, it: &mut impl FnMut(&Pat<'_>) -> bool) -> bool { @@ -1118,26 +1084,15 @@ impl UnOp { } /// A statement. -#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub struct Stmt<'hir> { pub hir_id: HirId, pub kind: StmtKind<'hir>, pub span: Span, } -impl fmt::Debug for Stmt<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "stmt({}: {})", - self.hir_id, - print::to_string(print::NO_ANN, |s| s.print_stmt(self)) - ) - } -} - /// The contents of a statement. -#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)] +#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub enum StmtKind<'hir> { /// A local (`let`) binding. Local(&'hir Local<'hir>), @@ -1351,7 +1306,7 @@ pub struct AnonConst { } /// An expression. -#[derive(RustcEncodable, RustcDecodable)] +#[derive(Debug, RustcEncodable, RustcDecodable)] pub struct Expr<'hir> { pub hir_id: HirId, pub kind: ExprKind<'hir>, @@ -1472,17 +1427,6 @@ impl Expr<'_> { } } -impl fmt::Debug for Expr<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!( - f, - "expr({}: {})", - self.hir_id, - print::to_string(print::NO_ANN, |s| s.print_expr(self)) - ) - } -} - /// Checks if the specified expression is a built-in range literal. /// (See: `LoweringContext::lower_expr()`). /// @@ -1965,19 +1909,13 @@ impl TypeBinding<'_> { } } -#[derive(RustcEncodable, RustcDecodable)] +#[derive(Debug, RustcEncodable, RustcDecodable)] pub struct Ty<'hir> { pub hir_id: HirId, pub kind: TyKind<'hir>, pub span: Span, } -impl fmt::Debug for Ty<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "type({})", print::to_string(print::NO_ANN, |s| s.print_type(self))) - } -} - /// Not represented directly in the AST; referred to by name through a `ty_path`. #[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)] #[derive(HashStable_Generic)] @@ -2182,15 +2120,6 @@ pub enum FnRetTy<'hir> { Return(&'hir Ty<'hir>), } -impl fmt::Display for FnRetTy<'_> { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - Self::Return(ref ty) => print::to_string(print::NO_ANN, |s| s.print_type(ty)).fmt(f), - Self::DefaultReturn(_) => "()".fmt(f), - } - } -} - impl FnRetTy<'_> { pub fn span(&self) -> Span { match *self { @@ -2274,13 +2203,10 @@ pub struct TraitRef<'hir> { impl TraitRef<'_> { /// Gets the `DefId` of the referenced trait. It _must_ actually be a trait or trait alias. - pub fn trait_def_id(&self) -> DefId { + pub fn trait_def_id(&self) -> Option { match self.path.res { - Res::Def(DefKind::Trait, did) => did, - Res::Def(DefKind::TraitAlias, did) => did, - Res::Err => { - FatalError.raise(); - } + Res::Def(DefKind::Trait | DefKind::TraitAlias, did) => Some(did), + Res::Err => None, _ => unreachable!(), } } diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 11749cf996b44..08b4ef1b918e1 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -121,6 +121,8 @@ impl<'a> FnKind<'a> { /// An abstract representation of the HIR `rustc::hir::map::Map`. pub trait Map<'hir> { + /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. + fn find(&self, hir_id: HirId) -> Option>; fn body(&self, id: BodyId) -> &'hir Body<'hir>; fn item(&self, id: HirId) -> &'hir Item<'hir>; fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir>; @@ -132,6 +134,9 @@ pub trait Map<'hir> { pub struct ErasedMap<'hir>(&'hir dyn Map<'hir>); impl<'hir> Map<'hir> for ErasedMap<'hir> { + fn find(&self, _: HirId) -> Option> { + None + } fn body(&self, id: BodyId) -> &'hir Body<'hir> { self.0.body(id) } diff --git a/src/librustc_hir/lib.rs b/src/librustc_hir/lib.rs index fbb3d6b2af37c..49692c73fad80 100644 --- a/src/librustc_hir/lib.rs +++ b/src/librustc_hir/lib.rs @@ -7,6 +7,7 @@ #![feature(const_fn)] // For the unsizing cast on `&[]` #![feature(const_panic)] #![feature(in_band_lifetimes)] +#![feature(or_patterns)] #![feature(specialization)] #![recursion_limit = "256"] @@ -23,7 +24,6 @@ pub mod intravisit; pub mod itemlikevisit; pub mod lang_items; pub mod pat_util; -pub mod print; mod stable_hash_impls; mod target; pub mod weak_lang_items; diff --git a/src/librustc_hir_pretty/Cargo.toml b/src/librustc_hir_pretty/Cargo.toml new file mode 100644 index 0000000000000..6a9339b4b9cee --- /dev/null +++ b/src/librustc_hir_pretty/Cargo.toml @@ -0,0 +1,18 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_hir_pretty" +version = "0.0.0" +edition = "2018" + +[lib] +name = "rustc_hir_pretty" +path = "lib.rs" +doctest = false + +[dependencies] +rustc_ast_pretty = { path = "../librustc_ast_pretty" } +rustc_hir = { path = "../librustc_hir" } +rustc_target = { path = "../librustc_target" } +rustc_data_structures = { path = "../librustc_data_structures" } +rustc_span = { path = "../librustc_span" } +rustc_ast = { path = "../librustc_ast" } diff --git a/src/librustc_hir/print.rs b/src/librustc_hir_pretty/lib.rs similarity index 97% rename from src/librustc_hir/print.rs rename to src/librustc_hir_pretty/lib.rs index cd16e451f1db8..06f338af9e92b 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -3,19 +3,22 @@ use rustc_ast::util::parser::{self, AssocOp, Fixity}; use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent}; use rustc_ast_pretty::pp::{self, Breaks}; use rustc_ast_pretty::pprust::{Comments, PrintState}; +use rustc_hir as hir; +use rustc_hir::{GenericArg, GenericParam, GenericParamKind, Node}; +use rustc_hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; use rustc_span::source_map::{SourceMap, Spanned}; use rustc_span::symbol::{kw, IdentPrinter}; use rustc_span::{self, BytePos, FileName}; use rustc_target::spec::abi::Abi; -use crate::hir; -use crate::hir::{GenericArg, GenericParam, GenericParamKind, Node}; -use crate::hir::{GenericBound, PatKind, RangeEnd, TraitBoundModifier}; - use std::borrow::Cow; use std::cell::Cell; use std::vec; +pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: hir::HirId) -> String { + to_string(&map, |s| s.print_node(map.find(hir_id).unwrap())) +} + pub enum AnnNode<'a> { Name(&'a ast::Name), Block(&'a hir::Block<'a>), @@ -47,7 +50,7 @@ pub struct NoAnn; impl PpAnn for NoAnn {} pub const NO_ANN: &dyn PpAnn = &NoAnn; -impl PpAnn for hir::Crate<'a> { +impl PpAnn for hir::Crate<'_> { fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item<'_>> { Some(self.item(item)) } @@ -62,6 +65,20 @@ impl PpAnn for hir::Crate<'a> { } } +/// Identical to the `PpAnn` implementation for `hir::Crate`, +/// except it avoids creating a dependency on the whole crate. +impl PpAnn for &dyn rustc_hir::intravisit::Map<'_> { + fn nested(&self, state: &mut State<'_>, nested: Nested) { + match nested { + Nested::Item(id) => state.print_item(self.item(id.id)), + Nested::TraitItem(id) => state.print_trait_item(self.trait_item(id)), + Nested::ImplItem(id) => state.print_impl_item(self.impl_item(id)), + Nested::Body(id) => state.print_expr(&self.body(id).value), + Nested::BodyParamPat(id, i) => state.print_pat(&self.body(id).params[i].pat), + } + } +} + pub struct State<'a> { pub s: pp::Printer, comments: Option>, @@ -1006,10 +1023,10 @@ impl<'a> State<'a> { close_box: bool, ) { match blk.rules { - hir::UnsafeBlock(..) => self.word_space("unsafe"), - hir::PushUnsafeBlock(..) => self.word_space("push_unsafe"), - hir::PopUnsafeBlock(..) => self.word_space("pop_unsafe"), - hir::DefaultBlock => (), + hir::BlockCheckMode::UnsafeBlock(..) => self.word_space("unsafe"), + hir::BlockCheckMode::PushUnsafeBlock(..) => self.word_space("push_unsafe"), + hir::BlockCheckMode::PopUnsafeBlock(..) => self.word_space("pop_unsafe"), + hir::BlockCheckMode::DefaultBlock => (), } self.maybe_print_comment(blk.span.lo()); self.ann.pre(self, AnnNode::Block(blk)); @@ -1092,7 +1109,7 @@ impl<'a> State<'a> { &mut self, qpath: &hir::QPath<'_>, fields: &[hir::Field<'_>], - wth: &Option<&'hir hir::Expr<'_>>, + wth: &Option<&hir::Expr<'_>>, ) { self.print_qpath(qpath, true); self.s.word("{"); @@ -1848,7 +1865,8 @@ impl<'a> State<'a> { self.print_block_unclosed(&blk); // If it is a user-provided unsafe block, print a comma after it - if let hir::UnsafeBlock(hir::UserProvided) = blk.rules { + if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = blk.rules + { self.s.word(","); } } @@ -1928,18 +1946,18 @@ impl<'a> State<'a> { }); self.s.word("|"); - if let hir::DefaultReturn(..) = decl.output { + if let hir::FnRetTy::DefaultReturn(..) = decl.output { return; } self.space_if_not_bol(); self.word_space("->"); match decl.output { - hir::Return(ref ty) => { + hir::FnRetTy::Return(ref ty) => { self.print_type(&ty); self.maybe_print_comment(ty.span.lo()) } - hir::DefaultReturn(..) => unreachable!(), + hir::FnRetTy::DefaultReturn(..) => unreachable!(), } } @@ -2112,7 +2130,7 @@ impl<'a> State<'a> { } pub fn print_fn_output(&mut self, decl: &hir::FnDecl<'_>) { - if let hir::DefaultReturn(..) = decl.output { + if let hir::FnRetTy::DefaultReturn(..) = decl.output { return; } @@ -2120,13 +2138,13 @@ impl<'a> State<'a> { self.ibox(INDENT_UNIT); self.word_space("->"); match decl.output { - hir::DefaultReturn(..) => unreachable!(), - hir::Return(ref ty) => self.print_type(&ty), + hir::FnRetTy::DefaultReturn(..) => unreachable!(), + hir::FnRetTy::Return(ref ty) => self.print_type(&ty), } self.end(); match decl.output { - hir::Return(ref output) => self.maybe_print_comment(output.span.lo()), + hir::FnRetTy::Return(ref output) => self.maybe_print_comment(output.span.lo()), _ => {} } } diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 088cba83ef998..ea439b1f41d42 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -19,6 +19,7 @@ rustc_attr = { path = "../librustc_attr" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } rustc_hir = { path = "../librustc_hir" } +rustc_hir_pretty = { path = "../librustc_hir_pretty" } rustc_target = { path = "../librustc_target" } rustc_index = { path = "../librustc_index" } rustc_serialize = { path = "../libserialize", package = "serialize" } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 9718d19281620..3686b2f20487b 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -824,8 +824,10 @@ impl EncodeContext<'tcx> { record!(self.per_def.kind[def_id] <- match trait_item.kind { ty::AssocKind::Const => { - let rendered = - hir::print::to_string(&self.tcx.hir(), |s| s.print_trait_item(ast_item)); + let rendered = rustc_hir_pretty::to_string( + &(&self.tcx.hir() as &dyn intravisit::Map<'_>), + |s| s.print_trait_item(ast_item) + ); let rendered_const = self.lazy(RenderedConst(rendered)); EntryKind::AssocConst( @@ -1044,8 +1046,11 @@ impl EncodeContext<'tcx> { } fn encode_rendered_const_for_body(&mut self, body_id: hir::BodyId) -> Lazy { - let body = self.tcx.hir().body(body_id); - let rendered = hir::print::to_string(&self.tcx.hir(), |s| s.print_expr(&body.value)); + let hir = self.tcx.hir(); + let body = hir.body(body_id); + let rendered = rustc_hir_pretty::to_string(&(&hir as &dyn intravisit::Map<'_>), |s| { + s.print_expr(&body.value) + }); let rendered_const = &RenderedConst(rendered); self.lazy(rendered_const) } diff --git a/src/librustc_passes/liveness.rs b/src/librustc_passes/liveness.rs index 97f6457d39736..e729c2d517fea 100644 --- a/src/librustc_passes/liveness.rs +++ b/src/librustc_passes/liveness.rs @@ -903,10 +903,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn compute(&mut self, body: &hir::Expr<'_>) -> LiveNode { - debug!( - "compute: using id for body, {}", - self.ir.tcx.hir().hir_to_pretty_string(body.hir_id) - ); + debug!("compute: using id for body, {:?}", body); // the fallthrough exit is only for those cases where we do not // explicitly return: @@ -979,7 +976,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { } fn propagate_through_expr(&mut self, expr: &Expr<'_>, succ: LiveNode) -> LiveNode { - debug!("propagate_through_expr: {}", self.ir.tcx.hir().hir_to_pretty_string(expr.hir_id)); + debug!("propagate_through_expr: {:?}", expr); match expr.kind { // Interesting cases with control flow or which gen/kill @@ -990,10 +987,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { hir::ExprKind::Field(ref e, _) => self.propagate_through_expr(&e, succ), hir::ExprKind::Closure(..) => { - debug!( - "{} is an ExprKind::Closure", - self.ir.tcx.hir().hir_to_pretty_string(expr.hir_id) - ); + debug!("{:?} is an ExprKind::Closure", expr); // the construction of a closure itself is not important, // but we have to consider the closed over variables. @@ -1344,11 +1338,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { let mut first_merge = true; let ln = self.live_node(expr.hir_id, expr.span); self.init_empty(ln, succ); - debug!( - "propagate_through_loop: using id for loop body {} {}", - expr.hir_id, - self.ir.tcx.hir().hir_to_pretty_string(body.hir_id) - ); + debug!("propagate_through_loop: using id for loop body {} {:?}", expr.hir_id, body); self.break_ln.insert(expr.hir_id, succ); diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 8734cee366abf..0df1d08cbd8bd 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1320,14 +1320,18 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { let is_local_static = if let DefKind::Static = kind { def_id.is_local() } else { false }; if !self.item_is_accessible(def_id) && !is_local_static { - let name = match *qpath { - hir::QPath::Resolved(_, ref path) => path.to_string(), - hir::QPath::TypeRelative(_, ref segment) => segment.ident.to_string(), + let sess = self.tcx.sess; + let sm = sess.source_map(); + let name = match qpath { + hir::QPath::Resolved(_, path) => sm.span_to_snippet(path.span).ok(), + hir::QPath::TypeRelative(_, segment) => Some(segment.ident.to_string()), }; let kind = kind.descr(def_id); - self.tcx - .sess - .struct_span_err(span, &format!("{} `{}` is private", kind, name)) + let msg = match name { + Some(name) => format!("{} `{}` is private", kind, name), + None => format!("{} is private", kind), + }; + sess.struct_span_err(span, &msg) .span_label(span, &format!("private {}", kind)) .emit(); return; diff --git a/src/librustc_save_analysis/Cargo.toml b/src/librustc_save_analysis/Cargo.toml index de851d9772727..623da1ddcb425 100644 --- a/src/librustc_save_analysis/Cargo.toml +++ b/src/librustc_save_analysis/Cargo.toml @@ -11,13 +11,14 @@ path = "lib.rs" [dependencies] log = "0.4" rustc = { path = "../librustc" } +rustc_ast = { path = "../librustc_ast" } rustc_ast_pretty = { path = "../librustc_ast_pretty" } rustc_data_structures = { path = "../librustc_data_structures" } -rustc_session = { path = "../librustc_session" } rustc_hir = { path = "../librustc_hir" } +rustc_hir_pretty = { path = "../librustc_hir_pretty" } rustc_parse = { path = "../librustc_parse" } serde_json = "1" -rustc_ast = { path = "../librustc_ast" } +rustc_session = { path = "../librustc_session" } rustc_span = { path = "../librustc_span" } rls-data = "0.19" rls-span = "0.5" diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 024633c3b3dec..21551eeddb927 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -404,14 +404,15 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) { Some(Node::Item(item)) => match item.kind { hir::ItemKind::Impl { ref self_ty, .. } => { + let hir = self.tcx.hir(); + let mut qualname = String::from("<"); - qualname.push_str(&self.tcx.hir().hir_to_pretty_string(self_ty.hir_id)); + qualname.push_str(&rustc_hir_pretty::id_to_string(&hir, self_ty.hir_id)); let trait_id = self.tcx.trait_id_of_impl(impl_id); let mut docs = String::new(); let mut attrs = vec![]; - let hir_id = self.tcx.hir().node_to_hir_id(id); - if let Some(Node::ImplItem(item)) = self.tcx.hir().find(hir_id) { + if let Some(Node::ImplItem(item)) = hir.find(hir.node_to_hir_id(id)) { docs = self.docs_for_attrs(&item.attrs); attrs = item.attrs.to_vec(); } diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs index 12939519fc28f..8cbed43cac01d 100644 --- a/src/librustc_trait_selection/traits/error_reporting/mod.rs +++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs @@ -1581,7 +1581,8 @@ impl<'a, 'tcx> InferCtxtPrivExt<'tcx> for InferCtxt<'a, 'tcx> { for param in generics.params { if param.span == *span && !param.bounds.iter().any(|bound| { - bound.trait_def_id() == self.tcx.lang_items().sized_trait() + bound.trait_ref().and_then(|trait_ref| trait_ref.trait_def_id()) + == self.tcx.lang_items().sized_trait() }) { let (span, separator) = match param.bounds { diff --git a/src/librustc_trait_selection/traits/object_safety.rs b/src/librustc_trait_selection/traits/object_safety.rs index 5cc1da045fc37..7d4ad61902a92 100644 --- a/src/librustc_trait_selection/traits/object_safety.rs +++ b/src/librustc_trait_selection/traits/object_safety.rs @@ -15,7 +15,7 @@ use crate::traits::query::evaluate_obligation::InferCtxtExt; use crate::traits::{self, Obligation, ObligationCause}; use rustc::ty::subst::{InternalSubsts, Subst}; use rustc::ty::{self, Predicate, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; -use rustc_errors::Applicability; +use rustc_errors::{Applicability, FatalError}; use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_session::lint::builtin::WHERE_CLAUSES_OBJECT_SAFETY; @@ -170,6 +170,24 @@ fn object_safety_violations_for_trait( violations } +fn sized_trait_bound_spans<'tcx>( + tcx: TyCtxt<'tcx>, + bounds: hir::GenericBounds<'tcx>, +) -> impl 'tcx + Iterator { + bounds.iter().filter_map(move |b| match b { + hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) + if trait_has_sized_self( + tcx, + trait_ref.trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()), + ) => + { + // Fetch spans for supertraits that are `Sized`: `trait T: Super` + Some(trait_ref.span) + } + _ => None, + }) +} + fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> { tcx.hir() .get_if_local(trait_def_id) @@ -189,33 +207,14 @@ fn get_sized_bounds(tcx: TyCtxt<'_>, trait_def_id: DefId) -> SmallVec<[Span; 1]> { // Fetch spans for trait bounds that are Sized: // `trait T where Self: Pred` - Some(pred.bounds.iter().filter_map(|b| match b { - hir::GenericBound::Trait( - trait_ref, - hir::TraitBoundModifier::None, - ) if trait_has_sized_self( - tcx, - trait_ref.trait_ref.trait_def_id(), - ) => - { - Some(trait_ref.span) - } - _ => None, - })) + Some(sized_trait_bound_spans(tcx, pred.bounds)) } _ => None, } }) .flatten() - .chain(bounds.iter().filter_map(|b| match b { - hir::GenericBound::Trait(trait_ref, hir::TraitBoundModifier::None) - if trait_has_sized_self(tcx, trait_ref.trait_ref.trait_def_id()) => - { - // Fetch spans for supertraits that are `Sized`: `trait T: Super` - Some(trait_ref.span) - } - _ => None, - })) + // Fetch spans for supertraits that are `Sized`: `trait T: Super`. + .chain(sized_trait_bound_spans(tcx, bounds)) .collect::>(), ), _ => None, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 54c646b855777..07630d7969e81 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -16,12 +16,11 @@ use rustc::ty::{GenericParamDef, GenericParamDefKind}; use rustc_ast::ast; use rustc_ast::util::lev_distance::find_best_match_for_name; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId}; +use rustc_errors::{pluralize, struct_span_err, Applicability, DiagnosticId, FatalError}; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def_id::DefId; -use rustc_hir::intravisit::{walk_generics, Visitor}; -use rustc_hir::print; +use rustc_hir::intravisit::{walk_generics, Visitor as _}; use rustc_hir::{Constness, GenericArg, GenericArgs}; use rustc_session::lint::builtin::{AMBIGUOUS_ASSOCIATED_ITEMS, LATE_BOUND_LIFETIME_ARGUMENTS}; use rustc_session::parse::feature_err; @@ -991,7 +990,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { self.ast_path_to_mono_trait_ref( trait_ref.path.span, - trait_ref.trait_def_id(), + trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()), self_ty, trait_ref.path.segments.last().unwrap(), ) @@ -1007,7 +1006,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { bounds: &mut Bounds<'tcx>, speculative: bool, ) -> Result<(), GenericArgCountMismatch> { - let trait_def_id = trait_ref.trait_def_id(); + let trait_def_id = trait_ref.trait_def_id().unwrap_or_else(|| FatalError.raise()); debug!("instantiate_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id); @@ -1118,6 +1117,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { if !self.tcx().features().unboxed_closures && trait_segment.generic_args().parenthesized != trait_def.paren_sugar { + let sess = &self.tcx().sess.parse_sess; // For now, require that parenthetical notation be used only with `Fn()` etc. let (msg, sugg) = if trait_def.paren_sugar { ( @@ -1132,7 +1132,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .and_then(|args| args.args.get(0)) .and_then(|arg| match arg { hir::GenericArg::Type(ty) => { - Some(print::to_string(print::NO_ANN, |s| s.print_type(ty))) + sess.source_map().span_to_snippet(ty.span).ok() } _ => None, }) @@ -1143,7 +1143,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .iter() .filter_map(|b| match (b.ident.as_str() == "Output", &b.kind) { (true, hir::TypeBindingKind::Equality { ty }) => { - Some(print::to_string(print::NO_ANN, |s| s.print_type(ty))) + sess.source_map().span_to_snippet(ty.span).ok() } _ => None, }) @@ -1154,7 +1154,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { } else { ("parenthetical notation is only stable when used with `Fn`-family traits", None) }; - let sess = &self.tcx().sess.parse_sess; let mut err = feature_err(sess, sym::unboxed_closures, span, msg); if let Some(sugg) = sugg { let msg = "use parenthetical notation instead"; diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index a34389b7d8968..b44bab2675d37 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -245,11 +245,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { { // check that the `if` expr without `else` is the fn body's expr if expr.span == span { - return self.get_fn_decl(hir_id).map(|(fn_decl, _)| { - ( - fn_decl.output.span(), - format!("expected `{}` because of this return type", fn_decl.output), - ) + return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| { + let span = fn_decl.output.span(); + let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?; + Some((span, format!("expected `{}` because of this return type", snippet))) }); } } diff --git a/src/librustc_typeck/check/callee.rs b/src/librustc_typeck/check/callee.rs index ec796043d3ac8..074951684ef06 100644 --- a/src/librustc_typeck/check/callee.rs +++ b/src/librustc_typeck/check/callee.rs @@ -265,7 +265,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let &ty::Adt(adt_def, ..) = t { if adt_def.is_enum() { if let hir::ExprKind::Call(ref expr, _) = call_expr.kind { - unit_variant = Some(self.tcx.hir().hir_to_pretty_string(expr.hir_id)) + unit_variant = + self.tcx.sess.source_map().span_to_snippet(expr.span).ok(); } } } @@ -335,16 +336,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.span_label(call_expr.span, "call expression requires function"); if let Some(span) = self.tcx.hir().res_span(def) { + let callee_ty = callee_ty.to_string(); let label = match (unit_variant, inner_callee_path) { - (Some(path), _) => format!("`{}` defined here", path), - (_, Some(hir::QPath::Resolved(_, path))) => format!( - "`{}` defined here returns `{}`", - path, - callee_ty.to_string() - ), - _ => format!("`{}` defined here", callee_ty.to_string()), + (Some(path), _) => Some(format!("`{}` defined here", path)), + (_, Some(hir::QPath::Resolved(_, path))) => { + self.tcx.sess.source_map().span_to_snippet(path.span).ok().map( + |p| format!("`{}` defined here returns `{}`", p, callee_ty), + ) + } + _ => Some(format!("`{}` defined here", callee_ty)), }; - err.span_label(span, label); + if let Some(label) = label { + err.span_label(span, label); + } } err.emit(); } else { diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 33fc18b4b6e68..2dc2a48ecbce8 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -1402,9 +1402,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> { { // Are of this `impl Trait`'s traits object safe? is_object_safe = bounds.iter().all(|bound| { - bound.trait_def_id().map_or(false, |def_id| { - fcx.tcx.object_safety_violations(def_id).is_empty() - }) + bound + .trait_ref() + .and_then(|t| t.trait_def_id()) + .map_or(false, |def_id| { + fcx.tcx.object_safety_violations(def_id).is_empty() + }) }) } } diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 0556c80e4f707..f7ffb5a2218ba 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -9,7 +9,7 @@ use rustc::ty::{self, AssocItem, Ty}; use rustc_ast::util::parser::PREC_POSTFIX; use rustc_errors::{Applicability, DiagnosticBuilder}; use rustc_hir as hir; -use rustc_hir::{is_range_literal, print, Node}; +use rustc_hir::{is_range_literal, Node}; use rustc_span::symbol::sym; use rustc_span::Span; @@ -198,13 +198,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { .peekable(); if compatible_variants.peek().is_some() { - let expr_text = - self.tcx.sess.source_map().span_to_snippet(expr.span).unwrap_or_else(|_| { - print::to_string(print::NO_ANN, |s| s.print_expr(expr)) - }); - let suggestions = compatible_variants.map(|v| format!("{}({})", v, expr_text)); - let msg = "try using a variant of the expected enum"; - err.span_suggestions(expr.span, msg, suggestions, Applicability::MaybeIncorrect); + if let Ok(expr_text) = self.tcx.sess.source_map().span_to_snippet(expr.span) { + let suggestions = compatible_variants.map(|v| format!("{}({})", v, expr_text)); + let msg = "try using a variant of the expected enum"; + err.span_suggestions( + expr.span, + msg, + suggestions, + Applicability::MaybeIncorrect, + ); + } } } } diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index dffed9a836c21..53a20d9e86788 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -475,7 +475,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { tcx.types.err } Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) => { - report_unexpected_variant_res(tcx, res, expr.span, qpath); + report_unexpected_variant_res(tcx, res, expr.span); tcx.types.err } _ => self.instantiate_value_path(segs, opt_ty, res, expr.span, expr.hir_id).0, @@ -696,10 +696,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self, &cause, &mut |db| { - db.span_label( - fn_decl.output.span(), - format!("expected `{}` because of this return type", fn_decl.output,), - ); + let span = fn_decl.output.span(); + if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) { + db.span_label( + span, + format!("expected `{}` because of this return type", snippet), + ); + } }, true, ); @@ -1668,20 +1671,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if let (Some(len), Ok(user_index)) = (len.try_eval_usize(self.tcx, self.param_env), field.as_str().parse::()) { - let base = self - .tcx - .sess - .source_map() - .span_to_snippet(base.span) - .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id)); - let help = "instead of using tuple indexing, use array indexing"; - let suggestion = format!("{}[{}]", base, field); - let applicability = if len < user_index { - Applicability::MachineApplicable - } else { - Applicability::MaybeIncorrect - }; - err.span_suggestion(expr.span, help, suggestion, applicability); + if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { + let help = "instead of using tuple indexing, use array indexing"; + let suggestion = format!("{}[{}]", base, field); + let applicability = if len < user_index { + Applicability::MachineApplicable + } else { + Applicability::MaybeIncorrect + }; + err.span_suggestion(expr.span, help, suggestion, applicability); + } } } @@ -1692,15 +1691,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { base: &hir::Expr<'_>, field: ast::Ident, ) { - let base = self - .tcx - .sess - .source_map() - .span_to_snippet(base.span) - .unwrap_or_else(|_| self.tcx.hir().hir_to_pretty_string(base.hir_id)); - let msg = format!("`{}` is a raw pointer; try dereferencing it", base); - let suggestion = format!("(*{}).{}", base, field); - err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect); + if let Ok(base) = self.tcx.sess.source_map().span_to_snippet(base.span) { + let msg = format!("`{}` is a raw pointer; try dereferencing it", base); + let suggestion = format!("(*{}).{}", base, field); + err.span_suggestion(expr.span, &msg, suggestion, Applicability::MaybeIncorrect); + } } fn no_such_field_err( diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index e940ecce0b9fb..688820029febc 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -1061,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let trait_def_ids: FxHashSet = param .bounds .iter() - .filter_map(|bound| bound.trait_def_id()) + .filter_map(|bound| Some(bound.trait_ref()?.trait_def_id()?)) .collect(); if !candidates.iter().any(|t| trait_def_ids.contains(&t.def_id)) { err.span_suggestions( diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e7ba00ac24507..c2930b30fe11d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2656,14 +2656,14 @@ pub fn check_enum<'tcx>( check_transparent(tcx, sp, def_id); } -fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span, qpath: &QPath<'_>) { +fn report_unexpected_variant_res(tcx: TyCtxt<'_>, res: Res, span: Span) { struct_span_err!( tcx.sess, span, E0533, - "expected unit struct, unit variant or constant, found {} `{}`", + "expected unit struct, unit variant or constant, found {}{}", res.descr(), - hir::print::to_string(&tcx.hir(), |s| s.print_qpath(qpath, false)) + tcx.sess.source_map().span_to_snippet(span).map_or(String::new(), |s| format!(" `{}`", s)), ) .emit(); } diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 0c4a05e61814d..ec703d5ec9e9a 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -171,9 +171,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { PatKind::TupleStruct(ref qpath, subpats, ddpos) => { self.check_pat_tuple_struct(pat, qpath, subpats, ddpos, expected, def_bm, ti) } - PatKind::Path(ref qpath) => { - self.check_pat_path(pat, path_res.unwrap(), qpath, expected, ti) - } + PatKind::Path(_) => self.check_pat_path(pat, path_res.unwrap(), expected, ti), PatKind::Struct(ref qpath, fields, etc) => { self.check_pat_struct(pat, qpath, fields, etc, expected, def_bm, ti) } @@ -694,7 +692,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &self, pat: &Pat<'_>, path_resolution: (Res, Option>, &'b [hir::PathSegment<'b>]), - qpath: &hir::QPath<'_>, expected: Ty<'tcx>, ti: TopInfo<'tcx>, ) -> Ty<'tcx> { @@ -707,17 +704,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { self.set_tainted_by_errors(); return tcx.types.err; } - Res::Def(DefKind::AssocFn, _) - | Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _) - | Res::Def(DefKind::Ctor(_, CtorKind::Fn), _) => { - report_unexpected_variant_res(tcx, res, pat.span, qpath); + Res::Def(DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fictive | CtorKind::Fn), _) => { + report_unexpected_variant_res(tcx, res, pat.span); return tcx.types.err; } - Res::Def(DefKind::Ctor(_, CtorKind::Const), _) - | Res::SelfCtor(..) - | Res::Def(DefKind::Const, _) - | Res::Def(DefKind::AssocConst, _) - | Res::Def(DefKind::ConstParam, _) => {} // OK + Res::SelfCtor(..) + | Res::Def( + DefKind::Ctor(_, CtorKind::Const) + | DefKind::Const + | DefKind::AssocConst + | DefKind::ConstParam, + _, + ) => {} // OK _ => bug!("unexpected pattern resolution: {:?}", res), } @@ -791,14 +789,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } }; let report_unexpected_res = |res: Res| { + let sm = tcx.sess.source_map(); + let path_str = sm + .span_to_snippet(sm.span_until_char(pat.span, '(')) + .map_or(String::new(), |s| format!(" `{}`", s.trim_end())); let msg = format!( - "expected tuple struct or tuple variant, found {} `{}`", + "expected tuple struct or tuple variant, found {}{}", res.descr(), - hir::print::to_string(&tcx.hir(), |s| s.print_qpath(qpath, false)), + path_str ); + let mut err = struct_span_err!(tcx.sess, pat.span, E0164, "{}", msg); - match (res, &pat.kind) { - (Res::Def(DefKind::Fn, _), _) | (Res::Def(DefKind::AssocFn, _), _) => { + match res { + Res::Def(DefKind::Fn | DefKind::AssocFn, _) => { err.span_label(pat.span, "`fn` calls are not allowed in patterns"); err.help( "for more information, visit \ diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index d0414af5b2138..9d8113e7b3fff 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -5,7 +5,6 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def_id::{DefId, DefIdSet, LOCAL_CRATE}; use rustc_hir::itemlikevisit::ItemLikeVisitor; -use rustc_hir::print::visibility_qualified; use rustc_session::lint; use rustc_span::Span; @@ -176,16 +175,13 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) { Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name), None => format!("use {};", item.ident.name), }; - - let replacement = visibility_qualified(&item.vis, base_replacement); - let msg = "`extern crate` is not idiomatic in the new edition"; - let help = format!("convert it to a `{}`", visibility_qualified(&item.vis, "use")); - - lint.build(msg) + let vis = tcx.sess.source_map().span_to_snippet(item.vis.span).unwrap_or_default(); + let add_vis = |to| if vis.is_empty() { to } else { format!("{} {}", vis, to) }; + lint.build("`extern crate` is not idiomatic in the new edition") .span_suggestion_short( extern_crate.span, - &help, - replacement, + &format!("convert it to a `{}`", add_vis("use".to_string())), + add_vis(base_replacement), Applicability::MachineApplicable, ) .emit(); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 42cd7246f086e..31123c5cf028c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -2146,13 +2146,18 @@ fn compute_sig_of_foreign_fn_decl<'tcx>( { let check = |ast_ty: &hir::Ty<'_>, ty: Ty<'_>| { if ty.is_simd() { + let snip = tcx + .sess + .source_map() + .span_to_snippet(ast_ty.span) + .map_or(String::new(), |s| format!(" `{}`", s)); tcx.sess .struct_span_err( ast_ty.span, &format!( - "use of SIMD type `{}` in FFI is highly experimental and \ + "use of SIMD type{} in FFI is highly experimental and \ may result in invalid code", - tcx.hir().hir_to_pretty_string(ast_ty.hir_id) + snip ), ) .help("add `#![feature(simd_ffi)]` to the crate attributes to enable") diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 153f7af9f97ca..510eae82834c8 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -482,8 +482,8 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet) } pub fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String { - if let Some(node_id) = cx.tcx.hir().as_local_hir_id(did) { - cx.tcx.hir().hir_to_pretty_string(node_id) + if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(did) { + rustc_hir_pretty::id_to_string(&cx.tcx.hir(), hir_id) } else { cx.tcx.rendered_const(did) } diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index 82e34710f0cbf..b3bfb559749cb 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -578,7 +578,7 @@ pub fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String { None }; - snippet.unwrap_or_else(|| cx.tcx.hir().hir_to_pretty_string(body.hir_id)) + snippet.unwrap_or_else(|| rustc_hir_pretty::id_to_string(&cx.tcx.hir(), body.hir_id)) } /// Given a type Path, resolve it to a Type using the TyCtxt diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 33cabad9193c4..3c5df0247c1e8 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -26,6 +26,7 @@ extern crate rustc_errors; extern crate rustc_expand; extern crate rustc_feature; extern crate rustc_hir; +extern crate rustc_hir_pretty; extern crate rustc_index; extern crate rustc_infer; extern crate rustc_interface; diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index c5aa4677d5659..93305a1f87a16 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -910,7 +910,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { fn visit_item(&mut self, item: &'hir hir::Item) { let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind { - self.map.hir_to_pretty_string(self_ty.hir_id) + rustc_hir_pretty::id_to_string(&self.map, self_ty.hir_id) } else { item.ident.to_string() }; diff --git a/src/test/ui/methods/method-path-in-pattern.stderr b/src/test/ui/methods/method-path-in-pattern.stderr index 1d1bdb6b052a8..ed3c0222c7542 100644 --- a/src/test/ui/methods/method-path-in-pattern.stderr +++ b/src/test/ui/methods/method-path-in-pattern.stderr @@ -4,13 +4,13 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f LL | Foo::bar => {} | ^^^^^^^^ -error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar` +error[E0533]: expected unit struct, unit variant or constant, found associated function `::bar` --> $DIR/method-path-in-pattern.rs:19:9 | LL | ::bar => {} | ^^^^^^^^^^ -error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::trait_bar` +error[E0533]: expected unit struct, unit variant or constant, found associated function `::trait_bar` --> $DIR/method-path-in-pattern.rs:23:9 | LL | ::trait_bar => {} @@ -22,7 +22,7 @@ error[E0533]: expected unit struct, unit variant or constant, found associated f LL | if let Foo::bar = 0u32 {} | ^^^^^^^^ -error[E0533]: expected unit struct, unit variant or constant, found associated function `Foo::bar` +error[E0533]: expected unit struct, unit variant or constant, found associated function `::bar` --> $DIR/method-path-in-pattern.rs:28:12 | LL | if let ::bar = 0u32 {} diff --git a/src/test/ui/privacy/associated-item-privacy-trait.rs b/src/test/ui/privacy/associated-item-privacy-trait.rs index 03347d5b99a31..b1482bc040f53 100644 --- a/src/test/ui/privacy/associated-item-privacy-trait.rs +++ b/src/test/ui/privacy/associated-item-privacy-trait.rs @@ -21,9 +21,9 @@ mod priv_trait { Pub.method(); //~^ ERROR type `for<'r> fn(&'r Self) {::method}` is private ::CONST; - //~^ ERROR associated constant `PrivTr::CONST` is private + //~^ ERROR associated constant `::CONST` is private let _: ::AssocTy; - //~^ ERROR associated type `PrivTr::AssocTy` is private + //~^ ERROR associated type `::AssocTy` is private pub type InSignatureTy = ::AssocTy; //~^ ERROR trait `priv_trait::PrivTr` is private pub trait InSignatureTr: PrivTr {} @@ -115,7 +115,7 @@ mod priv_parent_substs { >::CONST; //~^ ERROR type `priv_parent_substs::Priv` is private - let _: ::AssocTy; // FIXME no longer an error?! + let _: ::AssocTy; // FIXME no longer an error?! let _: >::AssocTy; //~^ ERROR type `priv_parent_substs::Priv` is private let _: >::AssocTy; diff --git a/src/test/ui/privacy/associated-item-privacy-trait.stderr b/src/test/ui/privacy/associated-item-privacy-trait.stderr index c30cc947d4508..b9f3e35d72261 100644 --- a/src/test/ui/privacy/associated-item-privacy-trait.stderr +++ b/src/test/ui/privacy/associated-item-privacy-trait.stderr @@ -31,7 +31,7 @@ LL | priv_trait::mac!(); | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: associated constant `PrivTr::CONST` is private +error: associated constant `::CONST` is private --> $DIR/associated-item-privacy-trait.rs:23:9 | LL | ::CONST; @@ -42,7 +42,7 @@ LL | priv_trait::mac!(); | = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) -error: associated type `PrivTr::AssocTy` is private +error: associated type `::AssocTy` is private --> $DIR/associated-item-privacy-trait.rs:25:16 | LL | let _: ::AssocTy; diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr index 7ff43f4404c54..4214e2503c345 100644 --- a/src/test/ui/qualified/qualified-path-params.stderr +++ b/src/test/ui/qualified/qualified-path-params.stderr @@ -1,4 +1,4 @@ -error[E0533]: expected unit struct, unit variant or constant, found associated function `<::A>::f` +error[E0533]: expected unit struct, unit variant or constant, found associated function `::A::f::` --> $DIR/qualified-path-params.rs:20:9 | LL | ::A::f:: => {}