};
build.cc.insert(target, compiler);
- build.verbose(&format!("CC_{} = {:?}", &target, build.cc(target)));
- build.verbose(&format!("CFLAGS_{} = {:?}", &target, build.cflags(target, GitRepo::Rustc)));
- if let Some(ar) = ar {
- build.verbose(&format!("AR_{} = {:?}", &target, ar));
- build.ar.insert(target, ar);
- }
- }
+ let cflags = build.cflags(target, GitRepo::Rustc);
- // For all host triples we need to find a C++ compiler as well
- let hosts = build.hosts.iter().cloned().chain(iter::once(build.build)).collect::<HashSet<_>>();
- for host in hosts.into_iter() {
+ // If we use llvm-libunwind, we will need a C++ compiler as well for all targets
+ // We'll need one anyways if the target triple is also a host triple
let mut cfg = cc::Build::new();
cfg.cargo_metadata(false).opt_level(2).warnings(false).debug(false).cpp(true)
- .target(&host).host(&build.build);
- let config = build.config.target_config.get(&host);
- if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
+ .target(&target).host(&build.build);
+
+ let cxx_configured = if let Some(cxx) = config.and_then(|c| c.cxx.as_ref()) {
cfg.compiler(cxx);
+ true
+ } else if build.hosts.contains(&target) || build.build == target {
+ set_compiler(&mut cfg, Language::CPlusPlus, target, config, build);
+ true
} else {
- set_compiler(&mut cfg, Language::CPlusPlus, host, config, build);
+ false
+ };
+
+ if cxx_configured {
+ let compiler = cfg.get_compiler();
+ build.cxx.insert(target, compiler);
+ }
+
+ build.verbose(&format!("CC_{} = {:?}", &target, build.cc(target)));
+ build.verbose(&format!("CFLAGS_{} = {:?}", &target, cflags));
+ if let Ok(cxx) = build.cxx(target) {
+ build.verbose(&format!("CXX_{} = {:?}", &target, cxx));
+ build.verbose(&format!("CXXFLAGS_{} = {:?}", &target, cflags));
+ }
+ if let Some(ar) = ar {
+ build.verbose(&format!("AR_{} = {:?}", &target, ar));
+ build.ar.insert(target, ar);
}
- let compiler = cfg.get_compiler();
- build.verbose(&format!("CXX_{} = {:?}", host, compiler.path()));
- build.cxx.insert(host, compiler);
}
}
pub trait Resolver {
/// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
- fn resolve_hir_path(
+ fn resolve_ast_path(
&mut self,
path: &ast::Path,
is_value: bool,
- ) -> hir::Path;
+ ) -> Res<NodeId>;
/// Obtain resolution for a `NodeId` with a single resolution.
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes>;
/// This should only return `None` during testing.
fn definitions(&mut self) -> &mut Definitions;
- /// Given suffix `["b", "c", "d"]`, creates a HIR path for `[::crate_root]::b::c::d` and
+ /// Given suffix `["b", "c", "d"]`, creates an AST path for `[::crate_root]::b::c::d` and
/// resolves it based on `is_value`.
fn resolve_str_path(
&mut self,
crate_root: Option<Symbol>,
components: &[Symbol],
is_value: bool,
- ) -> hir::Path;
+ ) -> (ast::Path, Res<NodeId>);
}
/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree,
params: Option<P<hir::GenericArgs>>,
is_value: bool,
) -> hir::Path {
- let mut path = self.resolver
+ let (path, res) = self.resolver
.resolve_str_path(span, self.crate_root, components, is_value);
- path.segments.last_mut().unwrap().args = params;
- for seg in path.segments.iter_mut() {
- if seg.hir_id.is_some() {
- seg.hir_id = Some(self.next_id());
+ let mut segments: Vec<_> = path.segments.iter().map(|segment| {
+ let res = self.expect_full_res(segment.id);
+ hir::PathSegment {
+ ident: segment.ident,
+ hir_id: Some(self.lower_node_id(segment.id)),
+ res: Some(self.lower_res(res)),
+ infer_args: true,
+ args: None,
}
+ }).collect();
+ segments.last_mut().unwrap().args = params;
+
+ hir::Path {
+ span,
+ res: res.map_id(|_| panic!("unexpected node_id")),
+ segments: segments.into(),
}
- path
}
fn ty_path(&mut self, mut hir_id: hir::HirId, span: Span, qpath: hir::QPath) -> hir::Ty {
match map.get(id) {
map::Node::Block(_) => {
// Use the parent, hopefully an expression node.
- Code::from_node(map, map.get_parent_node_by_hir_id(id))
+ Code::from_node(map, map.get_parent_node(id))
}
map::Node::Expr(expr) => Some(Code::Expr(expr)),
node => FnLikeNode::from_node(node).map(Code::FnLike)
}
fn def_kind(&self, hir_id: HirId) -> Option<DefKind> {
- let node = if let Some(node) = self.find_by_hir_id(hir_id) {
+ let node = if let Some(node) = self.find(hir_id) {
node
} else {
return None
if variant_data.ctor_hir_id().is_none() {
return None;
}
- let ctor_of = match self.find_by_hir_id(self.get_parent_node_by_hir_id(hir_id)) {
+ let ctor_of = match self.find(self.get_parent_node(hir_id)) {
Some(Node::Item(..)) => def::CtorOf::Struct,
Some(Node::Variant(..)) => def::CtorOf::Variant,
_ => unreachable!(),
/// which this is the body of, i.e., a `fn`, `const` or `static`
/// item (possibly associated), a closure, or a `hir::AnonConst`.
pub fn body_owner(&self, BodyId { hir_id }: BodyId) -> HirId {
- let parent = self.get_parent_node_by_hir_id(hir_id);
+ let parent = self.get_parent_node(hir_id);
assert!(self.lookup(parent).map_or(false, |e| e.is_body_owner(hir_id)));
parent
}
match self.get(id) {
Node::Item(&Item { node: ItemKind::Trait(..), .. }) |
Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id,
- Node::GenericParam(_) => self.get_parent_node_by_hir_id(id),
+ Node::GenericParam(_) => self.get_parent_node(id),
_ => bug!("ty_param_owner: {} not a type parameter", self.node_to_string(id))
}
}
/// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found.
pub fn get(&self, id: HirId) -> Node<'hir> {
// read recorded by `find`
- self.find_by_hir_id(id).unwrap_or_else(||
+ self.find(id).unwrap_or_else(||
bug!("couldn't find hir id {} in the HIR map", id))
}
}
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
- pub fn find(&self, id: NodeId) -> Option<Node<'hir>> {
- let hir_id = self.node_to_hir_id(id);
- self.find_by_hir_id(hir_id)
- }
-
- // FIXME(@ljedrz): replace the `NodeId` variant.
- pub fn find_by_hir_id(&self, hir_id: HirId) -> Option<Node<'hir>> {
+ pub fn find(&self, hir_id: HirId) -> Option<Node<'hir>> {
let result = self.find_entry(hir_id).and_then(|entry| {
if let Node::Crate = entry.node {
None
result
}
- /// Similar to `get_parent`; returns the parent node-ID, or just `hir_id` if there
- /// is no parent. Note that the parent may be `CRATE_NODE_ID`, which is not itself
+ /// Similar to `get_parent`; returns the parent HIR Id, or just `hir_id` if there
+ /// is no parent. Note that the parent may be `CRATE_HIR_ID`, which is not itself
/// present in the map, so passing the return value of `get_parent_node` to
/// `get` may in fact panic.
- /// This function returns the immediate parent in the AST, whereas `get_parent`
+ /// This function returns the immediate parent in the HIR, whereas `get_parent`
/// returns the enclosing item. Note that this might not be the actual parent
- /// node in the AST -- some kinds of nodes are not in the map and these will
+ /// node in the HIR -- some kinds of nodes are not in the map and these will
/// never appear as the parent node. Thus, you can always walk the parent nodes
- /// from a node to the root of the AST (unless you get back the same ID here,
+ /// from a node to the root of the HIR (unless you get back the same ID here,
/// which can happen if the ID is not in the map itself or is just weird).
- pub fn get_parent_node(&self, id: NodeId) -> NodeId {
- let hir_id = self.node_to_hir_id(id);
- let parent_hir_id = self.get_parent_node_by_hir_id(hir_id);
- self.hir_to_node_id(parent_hir_id)
- }
-
- // FIXME(@ljedrz): replace the `NodeId` variant.
- pub fn get_parent_node_by_hir_id(&self, hir_id: HirId) -> HirId {
+ pub fn get_parent_node(&self, hir_id: HirId) -> HirId {
if self.dep_graph.is_fully_enabled() {
let hir_id_owner = hir_id.owner;
let def_path_hash = self.definitions.def_path_hash(hir_id_owner);
/// Check if the node is an argument. An argument is a local variable whose
/// immediate parent is an item or a closure.
- pub fn is_argument(&self, id: NodeId) -> bool {
+ pub fn is_argument(&self, id: HirId) -> bool {
match self.find(id) {
Some(Node::Binding(_)) => (),
_ => return false,
{
let mut id = start_id;
loop {
- let parent_id = self.get_parent_node_by_hir_id(id);
+ let parent_id = self.get_parent_node(id);
if parent_id == CRATE_HIR_ID {
return Ok(CRATE_HIR_ID);
}
}
pub fn expect_item(&self, id: HirId) -> &'hir Item {
- match self.find_by_hir_id(id) { // read recorded by `find`
+ match self.find(id) { // read recorded by `find`
Some(Node::Item(item)) => item,
_ => bug!("expected item, found {}", self.node_to_string(id))
}
}
pub fn expect_impl_item(&self, id: HirId) -> &'hir ImplItem {
- match self.find_by_hir_id(id) {
+ match self.find(id) {
Some(Node::ImplItem(item)) => item,
_ => bug!("expected impl item, found {}", self.node_to_string(id))
}
}
pub fn expect_trait_item(&self, id: HirId) -> &'hir TraitItem {
- match self.find_by_hir_id(id) {
+ match self.find(id) {
Some(Node::TraitItem(item)) => item,
_ => bug!("expected trait item, found {}", self.node_to_string(id))
}
}
pub fn expect_variant_data(&self, id: HirId) -> &'hir VariantData {
- match self.find_by_hir_id(id) {
+ match self.find(id) {
Some(Node::Item(i)) => {
match i.node {
ItemKind::Struct(ref struct_def, _) |
}
pub fn expect_variant(&self, id: HirId) -> &'hir Variant {
- match self.find_by_hir_id(id) {
+ match self.find(id) {
Some(Node::Variant(variant)) => variant,
_ => bug!("expected variant, found {}", self.node_to_string(id)),
}
}
pub fn expect_foreign_item(&self, id: HirId) -> &'hir ForeignItem {
- match self.find_by_hir_id(id) {
+ match self.find(id) {
Some(Node::ForeignItem(item)) => item,
_ => bug!("expected foreign item, found {}", self.node_to_string(id))
}
}
pub fn expect_expr(&self, id: HirId) -> &'hir Expr {
- match self.find_by_hir_id(id) { // read recorded by find
+ match self.find(id) { // read recorded by find
Some(Node::Expr(expr)) => expr,
_ => bug!("expected expr, found {}", self.node_to_string(id))
}
Some(Node::Pat(pat)) => pat.span,
Some(Node::Arm(arm)) => arm.span,
Some(Node::Block(block)) => block.span,
- Some(Node::Ctor(..)) => match self.find_by_hir_id(
- self.get_parent_node_by_hir_id(hir_id))
+ Some(Node::Ctor(..)) => match self.find(
+ self.get_parent_node(hir_id))
{
Some(Node::Item(item)) => item.span,
Some(Node::Variant(variant)) => variant.span,
// chain, then returns `None`.
fn find_first_mod_parent<'a>(map: &'a Map<'_>, mut id: HirId) -> Option<(HirId, Name)> {
loop {
- if let Node::Item(item) = map.find_by_hir_id(id)? {
+ if let Node::Item(item) = map.find(id)? {
if item_is_mod(&item) {
return Some((id, item.ident.name))
}
})
};
- match map.find_by_hir_id(id) {
+ match map.find(id) {
Some(Node::Item(item)) => {
let item_str = match item.node {
ItemKind::ExternCrate(..) => "extern crate",
)
};
let span = scope.span(self, region_scope_tree);
- let tag = match self.hir().find_by_hir_id(scope.hir_id(region_scope_tree)) {
+ let tag = match self.hir().find(scope.hir_id(region_scope_tree)) {
Some(Node::Block(_)) => "block",
Some(Node::Expr(expr)) => match expr.node {
hir::ExprKind::Call(..) => "call",
let scope = region.free_region_binding_scope(self);
let node = self.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID);
- let tag = match self.hir().find_by_hir_id(node) {
+ let tag = match self.hir().find(node) {
Some(Node::Block(_)) | Some(Node::Expr(_)) => "body",
Some(Node::Item(it)) => Self::item_scope_tag(&it),
Some(Node::TraitItem(it)) => Self::trait_item_scope_tag(&it),
/// Track how many errors were reported when this infcx is created.
/// If the number of errors increases, that's also a sign (line
/// `tained_by_errors`) to avoid reporting certain kinds of errors.
+ // FIXME(matthewjasper) Merge into `tainted_by_errors_flag`
err_count_on_creation: usize,
/// This flag is true while there is an active snapshot.
.local_def_id_from_hir_id(opaque_parent_hir_id)
};
let (in_definition_scope, origin) =
- match tcx.hir().find_by_hir_id(opaque_hir_id)
+ match tcx.hir().find(opaque_hir_id)
{
Some(Node::Item(item)) => match item.node {
// Anonymous `impl Trait`
// function, then we should explore its block to check for codes that
// may need to be marked as live.
fn should_explore<'tcx>(tcx: TyCtxt<'tcx>, hir_id: hir::HirId) -> bool {
- match tcx.hir().find_by_hir_id(hir_id) {
+ match tcx.hir().find(hir_id) {
Some(Node::Item(..)) |
Some(Node::ImplItem(..)) |
Some(Node::ForeignItem(..)) |
// tuple struct constructor function
let id = self.struct_constructors.get(&id).cloned().unwrap_or(id);
- if let Some(node) = self.tcx.hir().find_by_hir_id(id) {
+ if let Some(node) = self.tcx.hir().find(id) {
self.live_symbols.insert(id);
self.visit_node(node);
}
use std::io::prelude::*;
use std::io;
use std::rc::Rc;
-use syntax::ast::{self, NodeId};
+use syntax::ast;
use syntax::ptr::P;
use syntax::symbol::{kw, sym};
use syntax_pos::Span;
// Don't run unused pass for #[derive()]
if let FnKind::Method(..) = fk {
let parent = ir.tcx.hir().get_parent_item(id);
- if let Some(Node::Item(i)) = ir.tcx.hir().find_by_hir_id(parent) {
+ if let Some(Node::Item(i)) = ir.tcx.hir().find(parent) {
if i.attrs.iter().any(|a| a.check_name(sym::automatically_derived)) {
return;
}
}
}
- fn access_var(&mut self, hir_id: HirId, nid: NodeId, succ: LiveNode, acc: u32, span: Span)
+ fn access_var(&mut self, hir_id: HirId, var_hid: HirId, succ: LiveNode, acc: u32, span: Span)
-> LiveNode {
let ln = self.live_node(hir_id, span);
if acc != 0 {
self.init_from_succ(ln, succ);
- let var_hid = self.ir.tcx.hir().node_to_hir_id(nid);
let var = self.variable(var_hid, span);
self.acc(ln, var, acc);
}
Res::Local(hid) => {
let upvars = self.ir.tcx.upvars(self.ir.body_owner);
if !upvars.map_or(false, |upvars| upvars.contains_key(&hid)) {
- let nid = self.ir.tcx.hir().hir_to_node_id(hid);
- self.access_var(hir_id, nid, succ, acc, path.span)
+ self.access_var(hir_id, hid, succ, acc, path.span)
} else {
succ
}
"non-place".into()
}
Categorization::Local(vid) => {
- if tcx.hir().is_argument(tcx.hir().hir_to_node_id(vid)) {
+ if tcx.hir().is_argument(vid) {
"argument"
} else {
"local variable"
return true
}
if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_src) {
- match tcx.hir().find_by_hir_id(impl_hir_id) {
+ match tcx.hir().find(impl_hir_id) {
Some(Node::Item(item)) =>
item_might_be_inlined(tcx, &item, codegen_fn_attrs),
Some(..) | None =>
None => { return false; }
};
- match self.tcx.hir().find_by_hir_id(hir_id) {
+ match self.tcx.hir().find(hir_id) {
Some(Node::Item(item)) => {
match item.node {
hir::ItemKind::Fn(..) =>
continue
}
- if let Some(ref item) = self.tcx.hir().find_by_hir_id(search_item) {
+ if let Some(ref item) = self.tcx.hir().find(search_item) {
self.propagate_node(item, search_item);
}
}
if let Some(Region::LateBound(_, def_id, _)) = def {
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(def_id) {
// Ensure that the parent of the def is an item, not HRTB
- let parent_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let parent_id = self.tcx.hir().get_parent_node(hir_id);
let parent_impl_id = hir::ImplItemId { hir_id: parent_id };
let parent_trait_id = hir::TraitItemId { hir_id: parent_id };
let krate = self.tcx.hir().forest.krate();
}
};
if let Node::Lifetime(hir_lifetime) = self.tcx.hir().get(lifetime.hir_id) {
- if let Some(parent) = self.tcx.hir().find_by_hir_id(
+ if let Some(parent) = self.tcx.hir().find(
self.tcx.hir().get_parent_item(hir_lifetime.hir_id))
{
match parent {
// and whether there's a `self` argument (treated specially).
let mut assoc_item_kind = None;
let mut impl_self = None;
- let parent = self.tcx.hir().get_parent_node_by_hir_id(output.hir_id);
+ let parent = self.tcx.hir().get_parent_node(output.hir_id);
let body = match self.tcx.hir().get(parent) {
// `fn` definitions and methods.
Node::Item(&hir::Item {
self.diagnostic().abort_if_errors();
}
pub fn compile_status(&self) -> Result<(), ErrorReported> {
- compile_result_from_err_count(self.err_count())
+ if self.has_errors() {
+ Err(ErrorReported)
+ } else {
+ Ok(())
+ }
}
+ // FIXME(matthewjasper) Remove this method, it should never be needed.
pub fn track_errors<F, T>(&self, f: F) -> Result<T, ErrorReported>
where
F: FnOnce() -> T,
}
pub type CompileResult = Result<(), ErrorReported>;
-
-pub fn compile_result_from_err_count(err_count: usize) -> CompileResult {
- if err_count == 0 {
- Ok(())
- } else {
- Err(ErrorReported)
- }
-}
err: &mut DiagnosticBuilder<'tcx>,
) {
if let &ObligationCauseCode::VariableType(hir_id) = code {
- let parent_node = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
- if let Some(Node::Local(ref local)) = self.tcx.hir().find_by_hir_id(parent_node) {
+ let parent_node = self.tcx.hir().get_parent_node(hir_id);
+ if let Some(Node::Local(ref local)) = self.tcx.hir().find(parent_node) {
if let Some(ref expr) = local.init {
if let hir::ExprKind::Index(_, _) = expr.node {
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(expr.span) {
trait_ref: &ty::Binder<ty::TraitRef<'tcx>>,
) {
let hir = self.tcx.hir();
- let parent_node = hir.get_parent_node_by_hir_id(obligation.cause.body_id);
- let node = hir.find_by_hir_id(parent_node);
+ let parent_node = hir.get_parent_node(obligation.cause.body_id);
+ let node = hir.find(parent_node);
if let Some(hir::Node::Item(hir::Item {
node: hir::ItemKind::Fn(decl, _, _, body_id),
..
let hir_id = self.hir()
.as_local_hir_id(suitable_region_binding_scope)
.unwrap();
- let is_impl_item = match self.hir().find_by_hir_id(hir_id) {
+ let is_impl_item = match self.hir().find(hir_id) {
Some(Node::Item(..)) | Some(Node::TraitItem(..)) => false,
Some(Node::ImplItem(..)) => {
self.is_bound_region_in_impl_item(suitable_region_binding_scope)
if lint::maybe_lint_level_root(self, id) {
return id;
}
- let next = self.hir().get_parent_node_by_hir_id(id);
+ let next = self.hir().get_parent_node(id);
if next == id {
bug!("lint traversal reached the root of the crate");
}
if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
return pair
}
- let next = self.hir().get_parent_node_by_hir_id(id);
+ let next = self.hir().get_parent_node(id);
if next == id {
bug!("lint traversal reached the root of the crate");
}
use std::mem;
use smallvec::SmallVec;
-use syntax::ast::CRATE_NODE_ID;
+use rustc::hir::CRATE_HIR_ID;
use crate::ty::context::TyCtxt;
use crate::ty::{DefId, DefIdTree};
/// crate.
#[inline]
pub fn full(tcx: TyCtxt<'tcx>) -> DefIdForest {
- let crate_id = tcx.hir().local_def_id(CRATE_NODE_ID);
+ let crate_id = tcx.hir().local_def_id_from_hir_id(CRATE_HIR_ID);
DefIdForest::from_id(crate_id)
}
self.ty_inhabitedness_forest(ty).contains(self, module)
}
- pub fn is_ty_uninhabited_from_all_modules(self, ty: Ty<'tcx>) -> bool {
+ pub fn is_ty_uninhabited_from_any_module(self, ty: Ty<'tcx>) -> bool {
!self.ty_inhabitedness_forest(ty).is_empty()
}
/// with a reference to the let
fn get_pattern_source<'tcx>(tcx: TyCtxt<'tcx>, pat: &Pat) -> PatternSource<'tcx> {
- let parent = tcx.hir().get_parent_node_by_hir_id(pat.hir_id);
+ let parent = tcx.hir().get_parent_node(pat.hir_id);
match tcx.hir().get(parent) {
Node::Expr(ref e) => {
if let ty::ReScope(scope) = *super_scope {
let hir_id = scope.hir_id(&self.region_scope_tree);
- match self.tcx.hir().find_by_hir_id(hir_id) {
+ match self.tcx.hir().find(hir_id) {
Some(Node::Stmt(_)) => {
if *sub_scope != ty::ReStatic {
db.note("consider using a `let` binding to increase its lifetime");
}
fn local_ty(&self, hir_id: hir::HirId) -> (Option<&hir::Ty>, bool) {
- let parent = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let parent = self.tcx.hir().get_parent_node(hir_id);
let parent_node = self.tcx.hir().get(parent);
// The parent node is like a fn
},
)) = ty.map(|t| &t.node)
{
- let borrow_expr_id = self.tcx.hir().get_parent_node_by_hir_id(borrowed_hir_id);
+ let borrow_expr_id = self.tcx.hir().get_parent_node(borrowed_hir_id);
db.span_suggestion(
self.tcx.hir().span(borrow_expr_id),
"consider removing the `&mut`, as it is an \
fn pp_ann<'a>(&'a self) -> &'a dyn pprust_hir::PpAnn;
/// Computes an user-readable representation of a path, if possible.
- fn node_path(&self, id: ast::NodeId) -> Option<String> {
+ fn node_path(&self, id: hir::HirId) -> Option<String> {
self.hir_map().and_then(|map| {
- let hir_id = map.node_to_hir_id(id);
- map.def_path_from_hir_id(hir_id)
+ map.def_path_from_hir_id(id)
}).map(|path| {
path.data
.into_iter()
self
}
- fn node_path(&self, id: ast::NodeId) -> Option<String> {
- Some(self.tcx.def_path_str(self.tcx.hir().local_def_id(id)))
+ fn node_path(&self, id: hir::HirId) -> Option<String> {
+ Some(self.tcx.def_path_str(self.tcx.hir().local_def_id_from_hir_id(id)))
}
}
if let Some(n) = hir::map::blocks::FnLikeNode::from_node(node) {
break n.body();
}
- let parent = tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let parent = tcx.hir().get_parent_node(hir_id);
assert_ne!(hir_id, parent);
hir_id = parent;
}
let node = hir_map.get(hir_id);
pp_state.print_node(node)?;
pp_state.s.space()?;
- let path = annotation.node_path(node_id)
+ let path = annotation.node_path(hir_id)
.expect("-Z unpretty missing node paths");
pp_state.synth_comment(path)?;
pp_state.s.hardbreak()?;
let nodeid =
nodeid.expect("`pretty flowgraph=..` needs NodeId (int) or unique path \
suffix (b::c::d)");
- let node = tcx.hir().find(nodeid).unwrap_or_else(|| {
+ let hir_id = tcx.hir().node_to_hir_id(nodeid);
+ let node = tcx.hir().find(hir_id).unwrap_or_else(|| {
tcx.sess.fatal(&format!("--pretty flowgraph couldn't find id: {}", nodeid))
});
- let hir_id = tcx.hir().node_to_hir_id(nodeid);
match blocks::Code::from_node(&tcx.hir(), hir_id) {
Some(code) => {
let variants = gather_flowgraph_variants(tcx.sess);
pub struct Handler {
pub flags: HandlerFlags,
+ /// The number of errors that have been emitted, including duplicates.
+ ///
+ /// This is not necessarily the count that's reported to the user once
+ /// compilation ends.
err_count: AtomicUsize,
+ deduplicated_err_count: AtomicUsize,
emitter: Lock<Box<dyn Emitter + sync::Send>>,
continue_after_error: AtomicBool,
delayed_span_bugs: Lock<Vec<Diagnostic>>,
impl Drop for Handler {
fn drop(&mut self) {
- if self.err_count() == 0 {
+ if !self.has_errors() {
let mut bugs = self.delayed_span_bugs.borrow_mut();
let has_bugs = !bugs.is_empty();
for bug in bugs.drain(..) {
Handler {
flags,
err_count: AtomicUsize::new(0),
+ deduplicated_err_count: AtomicUsize::new(0),
emitter: Lock::new(e),
continue_after_error: AtomicBool::new(true),
delayed_span_bugs: Lock::new(Vec::new()),
pub fn reset_err_count(&self) {
// actually frees the underlying memory (which `clear` would not do)
*self.emitted_diagnostics.borrow_mut() = Default::default();
+ self.deduplicated_err_count.store(0, SeqCst);
self.err_count.store(0, SeqCst);
}
}
pub fn print_error_count(&self, registry: &Registry) {
- let s = match self.err_count() {
+ let s = match self.deduplicated_err_count.load(SeqCst) {
0 => return,
1 => "aborting due to previous error".to_string(),
- _ => format!("aborting due to {} previous errors", self.err_count())
+ count => format!("aborting due to {} previous errors", count)
};
if self.treat_err_as_bug() {
return;
}
pub fn abort_if_errors(&self) {
- if self.err_count() == 0 {
- return;
+ if self.has_errors() {
+ FatalError.raise();
}
- FatalError.raise();
}
pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) {
if lvl == Warning && !self.flags.can_emit_warnings {
if self.emitted_diagnostics.borrow_mut().insert(diagnostic_hash) {
self.emitter.borrow_mut().emit_diagnostic(db);
if db.is_error() {
- self.bump_err_count();
+ self.deduplicated_err_count.fetch_add(1, SeqCst);
}
}
+ if db.is_error() {
+ self.bump_err_count();
+ }
}
pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
// lot of annoying errors in the compile-fail tests (basically,
// lint warnings and so on -- kindck used to do this abort, but
// kindck is gone now). -nmatsakis
- if sess.err_count() > 0 {
+ if sess.has_errors() {
return Err(ErrorReported);
}
// reported for missing docs.
let real_trait = trait_ref.path.res.def_id();
if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(real_trait) {
- match cx.tcx.hir().find_by_hir_id(hir_id) {
+ match cx.tcx.hir().find(hir_id) {
Some(Node::Item(item)) => {
if let hir::VisibilityKind::Inherited = item.vis.node {
for impl_item_ref in impl_item_refs {
return;
}
- let par_id = cx.tcx.hir().get_parent_node_by_hir_id(e.hir_id);
+ let par_id = cx.tcx.hir().get_parent_node(e.hir_id);
if let Node::Expr(par_e) = cx.tcx.hir().get(par_id) {
if let hir::ExprKind::Struct(..) = par_e.node {
if is_range_literal(cx.sess(), par_e)
_ => bug!(),
};
if lit_val < min || lit_val > max {
- let parent_id = cx.tcx.hir().get_parent_node_by_hir_id(e.hir_id);
+ let parent_id = cx.tcx.hir().get_parent_node(e.hir_id);
if let Node::Expr(par_e) = cx.tcx.hir().get(parent_id) {
match par_e.node {
hir::ExprKind::Cast(..) => {
err.span_label(span, format!("cannot {ACT}", ACT = act));
let upvar_hir_id = self.upvars[upvar_index.index()].var_hir_id;
- if let Some(Node::Binding(pat)) = self.infcx.tcx.hir().find_by_hir_id(upvar_hir_id)
+ if let Some(Node::Binding(pat)) = self.infcx.tcx.hir().find(upvar_hir_id)
{
if let hir::PatKind::Binding(
hir::BindingAnnotation::Unannotated,
let field = def.all_fields().nth(field.index())?;
// Use the HIR types to construct the diagnostic message.
let hir_id = tcx.hir().as_local_hir_id(field.did)?;
- let node = tcx.hir().find_by_hir_id(hir_id)?;
+ let node = tcx.hir().find(hir_id)?;
// Now we're dealing with the actual struct that we're going to suggest a change to,
// we can expect a field that is an immutable reference to a type.
if let hir::Node::Field(field) = node {
.into_iter()
.flatten()
.map(|(&var_hir_id, &upvar_id)| {
- let var_node_id = tcx_hir.hir_to_node_id(var_hir_id);
let capture = hir_tables.upvar_capture(upvar_id);
let by_ref = match capture {
ty::UpvarCapture::ByValue => false,
by_ref,
};
let mut mutability = Mutability::Not;
- if let Some(Node::Binding(pat)) = tcx_hir.find(var_node_id) {
+ if let Some(Node::Binding(pat)) = tcx_hir.find(var_hir_id) {
if let hir::PatKind::Binding(_, _, ident, _) = pat.node {
debuginfo.debug_name = ident.name;
if let Some(&bm) = hir.tables.pat_binding_modes().get(pat.hir_id) {
use rustc::ty::layout::{self, LayoutOf, VariantIdx};
use rustc::ty::subst::Subst;
use rustc::traits::Reveal;
-use rustc::util::common::ErrorReported;
use rustc_data_structures::fx::FxHashMap;
use syntax::source_map::{Span, DUMMY_SP};
if tcx.is_static(def_id) {
// Ensure that if the above error was either `TooGeneric` or `Reported`
// an error must be reported.
- let reported_err = tcx.sess.track_errors(|| {
- err.report_as_error(ecx.tcx,
- "could not evaluate static initializer")
- });
- match reported_err {
- Ok(v) => {
- tcx.sess.delay_span_bug(err.span,
- &format!("static eval failure did not emit an error: {:#?}",
- v));
- v
- },
- Err(ErrorReported) => ErrorHandled::Reported,
- }
+ let v = err.report_as_error(ecx.tcx, "could not evaluate static initializer");
+ tcx.sess.delay_span_bug(
+ err.span,
+ &format!("static eval failure did not emit an error: {:#?}", v)
+ );
+ v
} else if def_id.is_local() {
// constant defined in this crate, we can figure out a lint level!
match tcx.def_kind(def_id) {
Res::Def(DefKind::ConstParam, def_id) => {
let hir_id = cx.tcx.hir().as_local_hir_id(def_id).unwrap();
- let item_id = cx.tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let item_id = cx.tcx.hir().get_parent_node(hir_id);
let item_def_id = cx.tcx.hir().local_def_id_from_hir_id(item_id);
let generics = cx.tcx.generics_of(item_def_id);
let local_def_id = cx.tcx.hir().local_def_id_from_hir_id(hir_id);
));
}
} else {
- let callee_layout =
- self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?;
- if !callee_layout.abi.is_uninhabited() {
- return err!(FunctionRetMismatch(
- self.tcx.types.never, callee_layout.ty
- ));
+ let local = mir::RETURN_PLACE;
+ let ty = self.frame().body.local_decls[local].ty;
+ if !self.tcx.is_ty_uninhabited_from_any_module(ty) {
+ return err!(FunctionRetMismatch(self.tcx.types.never, ty));
}
}
Ok(())
used_unsafe: &FxHashSet<hir::HirId>,
id: hir::HirId,
) -> Option<(String, hir::HirId)> {
- let parent_id = tcx.hir().get_parent_node_by_hir_id(id);
+ let parent_id = tcx.hir().get_parent_node(id);
if parent_id != id {
if used_unsafe.contains(&parent_id) {
Some(("block".to_string(), parent_id))
} else if let Some(Node::Item(&hir::Item {
node: hir::ItemKind::Fn(_, header, _, _),
..
- })) = tcx.hir().find_by_hir_id(parent_id) {
+ })) = tcx.hir().find(parent_id) {
match header.unsafety {
hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)),
hir::Unsafety::Normal => None,
};
if loop_id != hir::DUMMY_HIR_ID {
- if let Node::Block(_) = self.hir_map.find_by_hir_id(loop_id).unwrap() {
+ if let Node::Block(_) = self.hir_map.find(loop_id).unwrap() {
return
}
}
match destination.target_id {
Ok(loop_id) => {
- if let Node::Block(block) = self.hir_map.find_by_hir_id(loop_id).unwrap() {
+ if let Node::Block(block) = self.hir_map.find(loop_id).unwrap() {
struct_span_err!(self.sess, e.span, E0696,
"`continue` pointing to a labeled block")
.span_label(e.span,
}
}
Node::Ctor(vdata) => {
- let parent_hir_id = tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let parent_hir_id = tcx.hir().get_parent_node(hir_id);
match tcx.hir().get(parent_hir_id) {
Node::Variant(..) => {
let parent_did = tcx.hir().local_def_id_from_hir_id(parent_hir_id);
if module_id == hir::CRATE_HIR_ID {
break
}
- module_id = self.tcx.hir().get_parent_node_by_hir_id(module_id);
+ module_id = self.tcx.hir().get_parent_node(module_id);
}
}
}
if let Some(hir_id) = self.tcx.hir().as_local_hir_id(did) {
// .. and it corresponds to a private type in the AST (this returns
// `None` for type parameters).
- match self.tcx.hir().find_by_hir_id(hir_id) {
+ match self.tcx.hir().find(hir_id) {
Some(Node::Item(ref item)) => !item.vis.node.is_pub(),
Some(_) | None => false,
}
has_old_errors = true;
break;
}
- let parent = self.tcx.hir().get_parent_node_by_hir_id(id);
+ let parent = self.tcx.hir().get_parent_node(id);
if parent == id {
break;
}
/// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that
/// the resolver is no longer needed as all the relevant information is inline.
impl<'a> hir::lowering::Resolver for Resolver<'a> {
- fn resolve_hir_path(
+ fn resolve_ast_path(
&mut self,
path: &ast::Path,
is_value: bool,
- ) -> hir::Path {
- self.resolve_hir_path_cb(path, is_value,
+ ) -> Res {
+ self.resolve_ast_path_cb(path, is_value,
|resolver, span, error| resolve_error(resolver, span, error))
}
crate_root: Option<Symbol>,
components: &[Symbol],
is_value: bool
- ) -> hir::Path {
+ ) -> (ast::Path, Res) {
let root = if crate_root.is_some() {
kw::PathRoot
} else {
segments,
};
- self.resolve_hir_path(&path, is_value)
+ let res = self.resolve_ast_path(&path, is_value);
+ (path, res)
}
fn get_partial_res(&mut self, id: NodeId) -> Option<PartialRes> {
/// and also it's a private type. Fortunately rustdoc doesn't need to know the error,
/// just that an error occurred.
pub fn resolve_str_path_error(&mut self, span: Span, path_str: &str, is_value: bool)
- -> Result<hir::Path, ()> {
+ -> Result<(ast::Path, Res), ()> {
let mut errored = false;
let path = if path_str.starts_with("::") {
.collect(),
}
};
- let path = self.resolve_hir_path_cb(&path, is_value, |_, _, _| errored = true);
- if errored || path.res == def::Res::Err {
+ let res = self.resolve_ast_path_cb(&path, is_value, |_, _, _| errored = true);
+ if errored || res == def::Res::Err {
Err(())
} else {
- Ok(path)
+ Ok((path, res))
}
}
- /// Like `resolve_hir_path`, but takes a callback in case there was an error.
- fn resolve_hir_path_cb<F>(
+ /// Like `resolve_ast_path`, but takes a callback in case there was an error.
+ // FIXME(eddyb) use `Result` or something instead of callbacks.
+ fn resolve_ast_path_cb<F>(
&mut self,
path: &ast::Path,
is_value: bool,
error_callback: F,
- ) -> hir::Path
+ ) -> Res
where F: for<'c, 'b> FnOnce(&'c mut Resolver<'_>, Span, ResolutionError<'b>)
{
let namespace = if is_value { ValueNS } else { TypeNS };
let span = path.span;
- let segments = &path.segments;
let path = Segment::from_path(&path);
// FIXME(Manishearth): intra-doc links won't get warned of epoch changes.
- let res = match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
+ match self.resolve_path_without_parent_scope(&path, Some(namespace), true,
span, CrateLint::No) {
PathResult::Module(ModuleOrUniformRoot::Module(module)) =>
module.res().unwrap(),
});
Res::Err
}
- };
-
- let segments: Vec<_> = segments.iter().map(|seg| {
- let mut hir_seg = hir::PathSegment::from_ident(seg.ident);
- hir_seg.res = Some(self.partial_res_map.get(&seg.id).map_or(def::Res::Err, |p| {
- p.base_res().map_id(|_| panic!("unexpected node_id"))
- }));
- hir_seg
- }).collect();
- hir::Path {
- span,
- res: res.map_id(|_| panic!("unexpected node_id")),
- segments: segments.into(),
}
}
fn suggest_macro_name(&mut self, name: Symbol, kind: MacroKind,
err: &mut DiagnosticBuilder<'a>, span: Span) {
+ if kind == MacroKind::Derive && (name.as_str() == "Send" || name.as_str() == "Sync") {
+ let msg = format!("unsafe traits like `{}` should be implemented explicitly", name);
+ err.span_note(span, &msg);
+ return;
+ }
+
// First check if this is a locally-defined bang macro.
let suggestion = if let MacroKind::Bang = kind {
find_best_match_for_name(
let mut decl_id = None;
let mut docs = String::new();
let mut attrs = vec![];
- if let Some(Node::ImplItem(item)) = self.tcx.hir().find(id) {
+ let hir_id = self.tcx.hir().node_to_hir_id(id);
+ if let Some(Node::ImplItem(item)) =
+ self.tcx.hir().find(hir_id)
+ {
docs = self.docs_for_attrs(&item.attrs);
attrs = item.attrs.to_vec();
}
Some(def_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::TraitItem(item)) = self.tcx.hir().find(id) {
+ if let Some(Node::TraitItem(item)) = self.tcx.hir().find(hir_id) {
docs = self.docs_for_attrs(&item.attrs);
attrs = item.attrs.to_vec();
}
}
match expr.node {
ast::ExprKind::Field(ref sub_ex, ident) => {
- let hir_node = match self.tcx.hir().find(sub_ex.id) {
+ let sub_ex_hir_id = self.tcx.hir().node_to_hir_id(sub_ex.id);
+ let hir_node = match self.tcx.hir().find(sub_ex_hir_id) {
Some(Node::Expr(expr)) => expr,
_ => {
debug!(
Node::PathSegment(seg) => {
match seg.res {
Some(res) if res != Res::Err => res,
- _ => self.get_path_res(self.tcx.hir().get_parent_node(id)),
+ _ => {
+ let parent_node = self.tcx.hir().get_parent_node(hir_id);
+ self.get_path_res(self.tcx.hir().hir_to_node_id(parent_node))
+ },
}
}
use crate::generated_code;
-use std::cell::Cell;
-
use syntax::parse::lexer::{self, StringReader};
use syntax::parse::token::{self, TokenKind};
use syntax_pos::*;
#[derive(Clone)]
pub struct SpanUtils<'a> {
pub sess: &'a Session,
- // FIXME given that we clone SpanUtils all over the place, this err_count is
- // probably useless and any logic relying on it is bogus.
- pub err_count: Cell<isize>,
}
impl<'a> SpanUtils<'a> {
pub fn new(sess: &'a Session) -> SpanUtils<'a> {
SpanUtils {
sess,
- err_count: Cell::new(0),
}
}
self.prohibit_generics(&path.segments);
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
- let item_id = tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let item_id = tcx.hir().get_parent_node(hir_id);
let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&def_id];
// Find the name and index of the const parameter by indexing the generics of the
// parent item and construct a `ParamConst`.
let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap();
- let item_id = tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let item_id = tcx.hir().get_parent_node(hir_id);
let item_def_id = tcx.hir().local_def_id_from_hir_id(item_id);
let generics = tcx.generics_of(item_def_id);
let index = generics.param_def_id_to_index[&tcx.hir().local_def_id_from_hir_id(hir_id)];
) {
let tcx = self.tcx;
if let PatKind::Binding(..) = inner.node {
- let parent_id = tcx.hir().get_parent_node_by_hir_id(pat.hir_id);
+ let parent_id = tcx.hir().get_parent_node(pat.hir_id);
let parent = tcx.hir().get(parent_id);
debug!("inner {:?} pat {:?} parent {:?}", inner, pat, parent);
match parent {
use hir::Node::{Block, Item, Local};
let hir = self.tcx.hir();
- let arm_id = hir.get_parent_node_by_hir_id(hir_id);
- let match_id = hir.get_parent_node_by_hir_id(arm_id);
- let containing_id = hir.get_parent_node_by_hir_id(match_id);
+ let arm_id = hir.get_parent_node(hir_id);
+ let match_id = hir.get_parent_node(arm_id);
+ let containing_id = hir.get_parent_node(match_id);
let node = hir.get(containing_id);
if let Block(block) = node {
// check that the body's parent is an fn
let parent = hir.get(
- hir.get_parent_node_by_hir_id(
- hir.get_parent_node_by_hir_id(block.hir_id),
+ hir.get_parent_node(
+ hir.get_parent_node(block.hir_id),
),
);
if let (Some(expr), Item(hir::Item {
callee_node: &hir::ExprKind,
callee_span: Span,
) {
- let hir_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
+ let hir_id = self.tcx.hir().get_parent_node(hir_id);
let parent_node = self.tcx.hir().get(hir_id);
if let (
hir::Node::Expr(hir::Expr { node: hir::ExprKind::Closure(_, _, _, sp, ..), .. }),
db.span_label(cause.span, "return type is not `()`");
}
ObligationCauseCode::BlockTailExpression(blk_id) => {
- let parent_id = fcx.tcx.hir().get_parent_node_by_hir_id(blk_id);
+ let parent_id = fcx.tcx.hir().get_parent_node(blk_id);
db = self.report_return_mismatched_types(
cause,
expected,
// Verify that this is a tail expression of a function, otherwise the
// label pointing out the cause for the type coercion will be wrong
// as prior return coercions would not be relevant (#57664).
- let parent_id = fcx.tcx.hir().get_parent_node_by_hir_id(id);
+ let parent_id = fcx.tcx.hir().get_parent_node(id);
let fn_decl = if let Some((expr, blk_id)) = expression {
pointing_at_return_type = fcx.suggest_mismatched_types_on_tail(
&mut db,
) -> Option<(Span, &'static str, String)> {
if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = expr.node {
if let hir::def::Res::Local(id) = path.res {
- let parent = self.tcx.hir().get_parent_node_by_hir_id(id);
+ let parent = self.tcx.hir().get_parent_node(id);
if let Some(Node::Expr(hir::Expr {
hir_id,
node: hir::ExprKind::Closure(_, decl, ..),
..
- })) = self.tcx.hir().find_by_hir_id(parent) {
- let parent = self.tcx.hir().get_parent_node_by_hir_id(*hir_id);
+ })) = self.tcx.hir().find(parent) {
+ let parent = self.tcx.hir().get_parent_node(*hir_id);
if let (Some(Node::Expr(hir::Expr {
node: hir::ExprKind::MethodCall(path, span, expr),
..
- })), 1) = (self.tcx.hir().find_by_hir_id(parent), decl.inputs.len()) {
+ })), 1) = (self.tcx.hir().find(parent), decl.inputs.len()) {
let self_ty = self.tables.borrow().node_type(expr[0].hir_id);
let self_ty = format!("{:?}", self_ty);
let name = path.ident.as_str();
sp: Span,
) -> bool {
let cm = self.sess().source_map();
- let parent_id = self.tcx.hir().get_parent_node_by_hir_id(hir_id);
- if let Some(parent) = self.tcx.hir().find_by_hir_id(parent_id) {
+ let parent_id = self.tcx.hir().get_parent_node(hir_id);
+ if let Some(parent) = self.tcx.hir().find(parent_id) {
// Account for fields
if let Node::Expr(hir::Expr {
node: hir::ExprKind::Struct(_, fields, ..), ..
if let Some(hir::Node::Expr(hir::Expr {
node: hir::ExprKind::Assign(left_expr, _),
..
- })) = self.tcx.hir().find_by_hir_id(
- self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id),
+ })) = self.tcx.hir().find(
+ self.tcx.hir().get_parent_node(expr.hir_id),
) {
if mutability == hir::Mutability::MutMutable {
// Found the following case:
if let Some(hir::Node::Expr(hir::Expr {
node: hir::ExprKind::Struct(_, fields, _),
..
- })) = self.tcx.hir().find_by_hir_id(self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id)) {
+ })) = self.tcx.hir().find(self.tcx.hir().get_parent_node(expr.hir_id)) {
// `expr` is a literal field for a struct, only suggest if appropriate
for field in fields {
if field.expr.hir_id == expr.hir_id && field.is_shorthand {
// else an error would have been flagged by the
// `loops` pass for using break with an expression
// where you are not supposed to.
- assert!(expr_opt.is_none() || self.tcx.sess.err_count() > 0);
+ assert!(expr_opt.is_none() || self.tcx.sess.has_errors());
}
ctxt.may_break = true;
// this can only happen if the `break` was not
// inside a loop at all, which is caught by the
// loop-checking pass.
- if self.tcx.sess.err_count() == 0 {
- self.tcx.sess.delay_span_bug(expr.span,
- "break was outside loop, but no error was emitted");
- }
+ self.tcx.sess.delay_span_bug(expr.span,
+ "break was outside loop, but no error was emitted");
// We still need to assign a type to the inner expression to
// prevent the ICE in #43162.
let filename = tcx.sess.source_map().span_to_filename(span);
let parent_node = self.tcx.hir().get(
- self.tcx.hir().get_parent_node_by_hir_id(hir_id),
+ self.tcx.hir().get_parent_node(hir_id),
);
let msg = format!(
"you must specify a type for this binding, like `{}`",
);
} else {
let call_expr = self.tcx.hir().expect_expr(
- self.tcx.hir().get_parent_node_by_hir_id(expr.hir_id),
+ self.tcx.hir().get_parent_node(expr.hir_id),
);
if let Some(span) = call_expr.span.trim_start(item_name.span) {
/// checking this function. On exit, if we find that *more* errors
/// have been reported, we will skip regionck and other work that
/// expects the types within the function to be consistent.
+ // FIXME(matthewjasper) This should not exist, and it's not correct
+ // if type checking is run in parallel.
err_count_on_creation: usize,
ret_coercion: Option<RefCell<DynamicCoerceMany<'tcx>>>,
fn visit_impl_item(&mut self, _: &'tcx hir::ImplItem) { }
}
-pub fn check_wf_new<'tcx>(tcx: TyCtxt<'tcx>) -> Result<(), ErrorReported> {
- tcx.sess.track_errors(|| {
- let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
- tcx.hir().krate().par_visit_all_item_likes(&mut visit);
- })
+pub fn check_wf_new<'tcx>(tcx: TyCtxt<'tcx>) {
+ let mut visit = wfcheck::CheckTypeWellFormedVisitor::new(tcx);
+ tcx.hir().krate().par_visit_all_item_likes(&mut visit);
}
fn check_mod_item_types<'tcx>(tcx: TyCtxt<'tcx>, module_def_id: DefId) {
&self.tcx.sess
}
- pub fn err_count_since_creation(&self) -> usize {
- self.tcx.sess.err_count() - self.err_count_on_creation
+ pub fn errors_reported_since_creation(&self) -> bool {
+ self.tcx.sess.err_count() > self.err_count_on_creation
}
/// Produces warning on the given node, if the current point in the
// If our calling expression is indeed the function itself, we're good!
// If not, generate an error that this can only be called directly.
if let Node::Expr(expr) = self.tcx.hir().get(
- self.tcx.hir().get_parent_node_by_hir_id(hir_id))
+ self.tcx.hir().get_parent_node(hir_id))
{
if let ExprKind::Call(ref callee, ..) = expr.node {
if callee.hir_id == hir_id {
let mut contained_in_place = false;
while let hir::Node::Expr(parent_expr) =
- self.tcx.hir().get(self.tcx.hir().get_parent_node_by_hir_id(expr_id))
+ self.tcx.hir().get(self.tcx.hir().get_parent_node(expr_id))
{
match &parent_expr.node {
hir::ExprKind::Assign(lhs, ..) | hir::ExprKind::AssignOp(_, lhs, ..) => {
} else if let ty::Error = leaf_ty.sty {
// If there is already another error, do not emit
// an error for not using a type Parameter.
- assert!(tcx.sess.err_count() > 0);
+ assert!(tcx.sess.has_errors());
return;
}
}
// standalone expr (e.g., the `E` in a type like `[u32; E]`).
rcx.outlives_environment.save_implied_bounds(id);
- if self.err_count_since_creation() == 0 {
+ if !self.errors_reported_since_creation() {
// regionck assumes typeck succeeded
rcx.visit_body(body);
rcx.visit_region_obligations(id);
self.param_env,
);
- if self.err_count_since_creation() == 0 {
+ if !self.errors_reported_since_creation() {
// regionck assumes typeck succeeded
rcx.visit_fn_body(fn_id, body, self.tcx.hir().span(fn_id));
}
// below it'll cause a panic because `def_id` is actually bogus at this
// point in time otherwise.
if let Some(id) = tcx.hir().as_local_hir_id(def_id) {
- if tcx.hir().find_by_hir_id(id).is_none() {
+ if tcx.hir().find(id).is_none() {
return false;
}
}
} else {
// Destructors only work on nominal types.
if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_did) {
- if let Some(Node::Item(item)) = tcx.hir().find_by_hir_id(impl_hir_id) {
+ if let Some(Node::Item(item)) = tcx.hir().find(impl_hir_id) {
let span = match item.node {
ItemKind::Impl(.., ref ty, _) => ty.span,
_ => item.span,
}
Node::AnonConst(_) => {
- let parent_node = tcx.hir().get(tcx.hir().get_parent_node_by_hir_id(hir_id));
+ let parent_node = tcx.hir().get(tcx.hir().get_parent_node(hir_id));
match parent_node {
Node::Ty(&hir::Ty {
node: hir::TyKind::Array(_, ref constant),
let main_t = tcx.type_of(main_def_id);
match main_t.sty {
ty::FnDef(..) => {
- if let Some(Node::Item(it)) = tcx.hir().find_by_hir_id(main_id) {
+ if let Some(Node::Item(it)) = tcx.hir().find(main_id) {
if let hir::ItemKind::Fn(.., ref generics, _) = it.node {
let mut error = false;
if !generics.params.is_empty() {
let start_t = tcx.type_of(start_def_id);
match start_t.sty {
ty::FnDef(..) => {
- if let Some(Node::Item(it)) = tcx.hir().find_by_hir_id(start_id) {
+ if let Some(Node::Item(it)) = tcx.hir().find(start_id) {
if let hir::ItemKind::Fn(.., ref generics, _) = it.node {
let mut error = false;
if !generics.params.is_empty() {
// this ensures that later parts of type checking can assume that items
// have valid types and not error
+ // FIXME(matthewjasper) We shouldn't need to do this.
tcx.sess.track_errors(|| {
time(tcx.sess, "type collecting", || {
for &module in tcx.hir().krate().modules.keys() {
})?;
}
- time(tcx.sess, "wf checking", || check::check_wf_new(tcx))?;
+ tcx.sess.track_errors(|| {
+ time(tcx.sess, "wf checking", || check::check_wf_new(tcx));
+ })?;
time(tcx.sess, "item-types checking", || {
for &module in tcx.hir().krate().modules.keys() {
// current architecture.
let resolver = abort_on_err(compiler.expansion(), sess).peek().1.clone();
- if sess.err_count() > 0 {
+ if sess.has_errors() {
sess.fatal("Compilation failed, aborting rustdoc");
}
})
});
- if let Ok(result) = result {
+ if let Ok((_, res)) = result {
+ let res = res.map_id(|_| panic!("unexpected node_id"));
// In case this is a trait item, skip the
// early return and try looking for the trait.
- let value = match result.res {
+ let value = match res {
Res::Def(DefKind::Method, _) | Res::Def(DefKind::AssocConst, _) => true,
Res::Def(DefKind::AssocTy, _) => false,
- Res::Def(DefKind::Variant, _) => return handle_variant(cx, result.res),
+ Res::Def(DefKind::Variant, _) => return handle_variant(cx, res),
// Not a trait item; just return what we found.
- _ => return Ok((result.res, None))
+ _ => return Ok((res, None))
};
if value != (ns == ValueNS) {
// FIXME: `with_scope` requires the `NodeId` of a module.
let node_id = cx.tcx.hir().hir_to_node_id(id);
- let ty = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| {
+ let (_, ty_res) = cx.enter_resolver(|resolver| resolver.with_scope(node_id, |resolver| {
resolver.resolve_str_path_error(DUMMY_SP, &path, false)
}))?;
- match ty.res {
+ let ty_res = ty_res.map_id(|_| panic!("unexpected node_id"));
+ match ty_res {
Res::Def(DefKind::Struct, did)
| Res::Def(DefKind::Union, did)
| Res::Def(DefKind::Enum, did)
ty::AssocKind::Const if ns == ValueNS => "associatedconstant",
_ => return Err(())
};
- Ok((ty.res, Some(format!("{}.{}", out, item_name))))
+ Ok((ty_res, Some(format!("{}.{}", out, item_name))))
} else {
match cx.tcx.type_of(did).sty {
ty::Adt(def, _) => {
.iter()
.find(|item| item.ident.name == item_name)
} {
- Ok((ty.res,
+ Ok((ty_res,
Some(format!("{}.{}",
if def.is_enum() {
"variant"
_ => return Err(())
};
- Ok((ty.res, Some(format!("{}.{}", kind, item_name))))
+ Ok((ty_res, Some(format!("{}.{}", kind, item_name))))
} else {
Err(())
}
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax_pos::Span;
-pub fn expand_deriving_unsafe_bound(cx: &mut ExtCtxt<'_>,
- span: Span,
- _: &MetaItem,
- _: &Annotatable,
- _: &mut dyn FnMut(Annotatable)) {
- cx.span_err(span, "this unsafe trait should be implemented explicitly");
-}
-
pub fn expand_deriving_copy(cx: &mut ExtCtxt<'_>,
span: Span,
mitem: &MetaItem,
"Default" => default::expand_deriving_default,
- "Send" => bounds::expand_deriving_unsafe_bound,
- "Sync" => bounds::expand_deriving_unsafe_bound,
"Copy" => bounds::expand_deriving_copy,
// deprecated
--- /dev/null
+// Test that we mark enum discriminant values as having errors, even when the
+// diagnostic is deduplicated.
+
+struct F;
+struct T;
+
+impl F {
+ const V: i32 = 0;
+}
+
+impl T {
+ const V: i32 = 0;
+}
+
+macro_rules! mac {
+ ($( $v: ident = $s: ident,)*) => {
+ enum E {
+ $( $v = $s::V, )*
+ //~^ ERROR mismatched types
+ }
+ }
+}
+
+mac! {
+ A = F,
+ B = T,
+}
+
+fn main() {}
--- /dev/null
+error[E0308]: mismatched types
+ --> $DIR/enum-discr-type-err.rs:18:21
+ |
+LL | $( $v = $s::V, )*
+ | ^^^^^ expected isize, found i32
+...
+LL | / mac! {
+LL | | A = F,
+LL | | B = T,
+LL | | }
+ | |_- in this macro invocation
+help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit
+ |
+LL | $( $v = $s::V.try_into().unwrap(), )*
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
--- /dev/null
+// compile-fail
+
+pub const unsafe fn fake_type<T>() -> T {
+ hint_unreachable()
+}
+
+pub const unsafe fn hint_unreachable() -> ! {
+ fake_type() //~ ERROR any use of this value will cause an error
+}
+
+trait Const {
+ const CONSTANT: i32 = unsafe { fake_type() };
+}
+
+impl <T> Const for T {}
+
+pub fn main() -> () {
+ dbg!(i32::CONSTANT); //~ ERROR erroneous constant used
+}
--- /dev/null
+error: any use of this value will cause an error
+ --> $DIR/uninhabited-const-issue-61744.rs:8:5
+ |
+LL | fake_type()
+ | ^^^^^^^^^^^
+ | |
+ | tried to call a function with return type T passing return place of type !
+ | inside call to `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:4:5
+ | inside call to `fake_type::<i32>` at $DIR/uninhabited-const-issue-61744.rs:12:36
+...
+LL | const CONSTANT: i32 = unsafe { fake_type() };
+ | ---------------------------------------------
+ |
+ = note: #[deny(const_err)] on by default
+
+error[E0080]: erroneous constant used
+ --> $DIR/uninhabited-const-issue-61744.rs:18:10
+ |
+LL | dbg!(i32::CONSTANT);
+ | ^^^^^^^^^^^^^ referenced constant has errors
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0080`.
#[derive(Send)]
-//~^ ERROR this unsafe trait should be implemented explicitly
+//~^ ERROR cannot find derive macro `Send` in this scope
struct Test;
#[derive(Sync)]
-//~^ ERROR this unsafe trait should be implemented explicitly
+//~^ ERROR cannot find derive macro `Sync` in this scope
struct Test1;
pub fn main() {}
-error: this unsafe trait should be implemented explicitly
+error: cannot find derive macro `Send` in this scope
+ --> $DIR/deriving-bounds.rs:1:10
+ |
+LL | #[derive(Send)]
+ | ^^^^
+ |
+note: unsafe traits like `Send` should be implemented explicitly
--> $DIR/deriving-bounds.rs:1:10
|
LL | #[derive(Send)]
| ^^^^
-error: this unsafe trait should be implemented explicitly
+error: cannot find derive macro `Sync` in this scope
+ --> $DIR/deriving-bounds.rs:5:10
+ |
+LL | #[derive(Sync)]
+ | ^^^^
+ |
+note: unsafe traits like `Sync` should be implemented explicitly
--> $DIR/deriving-bounds.rs:5:10
|
LL | #[derive(Sync)]
#[derive(Clone,
- Sync, //~ ERROR this unsafe trait should be implemented explicitly
+ Sync, //~ ERROR cannot find derive macro `Sync` in this scope
Copy)]
enum Foo {}
-error: this unsafe trait should be implemented explicitly
+error: cannot find derive macro `Sync` in this scope
+ --> $DIR/issue-33571.rs:2:10
+ |
+LL | Sync,
+ | ^^^^
+ |
+note: unsafe traits like `Sync` should be implemented explicitly
--> $DIR/issue-33571.rs:2:10
|
LL | Sync,
--- /dev/null
+// run-pass
+
+struct S<T> {
+ t : T,
+ s : Box<S<fn(u : T)>>
+}
+
+fn f(x : S<u32>) {}
+
+fn main () {}