diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 7f7a545df9605..bdf1b2332c2d5 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -895,25 +895,28 @@ impl<'a, 'gcx, 'tcx> HashStable> for hir::I fn hash_stable(&self, hcx: &mut StableHashingContext<'a, 'gcx, 'tcx>, hasher: &mut StableHasher) { - let node_id_hashing_mode = match self.node { - hir::ItemExternCrate(..) | + let (node_id_hashing_mode, hash_spans) = match self.node { hir::ItemStatic(..) | hir::ItemConst(..) | - hir::ItemFn(..) | - hir::ItemMod(..) | + hir::ItemFn(..) => { + (NodeIdHashingMode::Ignore, hcx.hash_spans()) + } + hir::ItemUse(..) => { + (NodeIdHashingMode::HashTraitsInScope, false) + } + + hir::ItemExternCrate(..) | hir::ItemForeignMod(..) | hir::ItemGlobalAsm(..) | + hir::ItemMod(..) | + hir::ItemDefaultImpl(..) | + hir::ItemTrait(..) | + hir::ItemImpl(..) | hir::ItemTy(..) | hir::ItemEnum(..) | hir::ItemStruct(..) | - hir::ItemUnion(..) | - hir::ItemTrait(..) | - hir::ItemDefaultImpl(..) | - hir::ItemImpl(..) => { - NodeIdHashingMode::Ignore - } - hir::ItemUse(..) => { - NodeIdHashingMode::HashTraitsInScope + hir::ItemUnion(..) => { + (NodeIdHashingMode::Ignore, false) } }; @@ -927,14 +930,16 @@ impl<'a, 'gcx, 'tcx> HashStable> for hir::I } = *self; hcx.hash_hir_item_like(attrs, |hcx| { - hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| { - id.hash_stable(hcx, hasher); + hcx.while_hashing_spans(hash_spans, |hcx| { + hcx.with_node_id_hashing_mode(node_id_hashing_mode, |hcx| { + id.hash_stable(hcx, hasher); + }); + name.hash_stable(hcx, hasher); + attrs.hash_stable(hcx, hasher); + node.hash_stable(hcx, hasher); + vis.hash_stable(hcx, hasher); + span.hash_stable(hcx, hasher); }); - name.hash_stable(hcx, hasher); - attrs.hash_stable(hcx, hasher); - node.hash_stable(hcx, hasher); - vis.hash_stable(hcx, hasher); - span.hash_stable(hcx, hasher); }); } } diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs index 0cc1993601119..61204b88e130e 100644 --- a/src/librustc_trans/debuginfo/metadata.rs +++ b/src/librustc_trans/debuginfo/metadata.rs @@ -14,7 +14,7 @@ use self::MemberDescriptionFactory::*; use self::EnumDiscriminantInfo::*; use super::utils::{debug_context, DIB, span_start, bytes_to_bits, size_and_align_of, - get_namespace_and_span_for_item, create_DIArray, is_node_local_to_unit}; + get_namespace_for_item, create_DIArray, is_node_local_to_unit}; use super::namespace::mangled_name_of_item; use super::type_names::compute_debuginfo_type_name; use super::{CrateDebugContext}; @@ -421,7 +421,7 @@ fn trait_pointer_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, let containing_scope = match trait_type.sty { ty::TyDynamic(ref data, ..) => if let Some(principal) = data.principal() { let def_id = principal.def_id(); - get_namespace_and_span_for_item(cx, def_id).0 + get_namespace_for_item(cx, def_id) } else { NO_SCOPE_METADATA }, @@ -971,7 +971,7 @@ fn prepare_struct_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, _ => bug!("prepare_struct_metadata on a non-ADT") }; - let (containing_scope, _) = get_namespace_and_span_for_item(cx, struct_def_id); + let containing_scope = get_namespace_for_item(cx, struct_def_id); let struct_metadata_stub = create_struct_stub(cx, struct_llvm_type, @@ -1096,7 +1096,7 @@ fn prepare_union_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, _ => bug!("prepare_union_metadata on a non-ADT") }; - let (containing_scope, _) = get_namespace_and_span_for_item(cx, union_def_id); + let containing_scope = get_namespace_for_item(cx, union_def_id); let union_metadata_stub = create_union_stub(cx, union_llvm_type, @@ -1483,7 +1483,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, -> RecursiveTypeDescription<'tcx> { let enum_name = compute_debuginfo_type_name(cx, enum_type, false); - let (containing_scope, _) = get_namespace_and_span_for_item(cx, enum_def_id); + let containing_scope = get_namespace_for_item(cx, enum_def_id); // FIXME: This should emit actual file metadata for the enum, but we // currently can't get the necessary information when it comes to types // imported from other crates. Formerly we violated the ODR when performing @@ -1781,7 +1781,8 @@ pub fn create_global_var_metadata(cx: &CrateContext, let tcx = cx.tcx(); let node_def_id = tcx.hir.local_def_id(node_id); - let (var_scope, span) = get_namespace_and_span_for_item(cx, node_def_id); + let var_scope = get_namespace_for_item(cx, node_def_id); + let span = cx.tcx().def_span(node_def_id); let (file_metadata, line_number) = if span != syntax_pos::DUMMY_SP { let loc = span_start(cx, span); diff --git a/src/librustc_trans/debuginfo/namespace.rs b/src/librustc_trans/debuginfo/namespace.rs index 54a129536d03d..d4dd112f3027f 100644 --- a/src/librustc_trans/debuginfo/namespace.rs +++ b/src/librustc_trans/debuginfo/namespace.rs @@ -10,8 +10,8 @@ // Namespace Handling. -use super::metadata::{file_metadata, unknown_file_metadata, UNKNOWN_LINE_NUMBER}; -use super::utils::{DIB, debug_context, span_start}; +use super::metadata::{unknown_file_metadata, UNKNOWN_LINE_NUMBER}; +use super::utils::{DIB, debug_context}; use llvm; use llvm::debuginfo::DIScope; @@ -19,10 +19,8 @@ use rustc::hir::def_id::DefId; use rustc::hir::map::DefPathData; use common::CrateContext; -use libc::c_uint; use std::ffi::CString; use std::ptr; -use syntax_pos::DUMMY_SP; pub fn mangled_name_of_item(ccx: &CrateContext, def_id: DefId, extra: &str) -> String { fn fill_nested(ccx: &CrateContext, def_id: DefId, extra: &str, output: &mut String) { @@ -69,21 +67,14 @@ pub fn item_namespace(ccx: &CrateContext, def_id: DefId) -> DIScope { }; let namespace_name = CString::new(namespace_name.as_bytes()).unwrap(); - let span = ccx.tcx().def_span(def_id); - let (file, line) = if span != DUMMY_SP { - let loc = span_start(ccx, span); - (file_metadata(ccx, &loc.file.name, def_id.krate), loc.line as c_uint) - } else { - (unknown_file_metadata(ccx), UNKNOWN_LINE_NUMBER) - }; let scope = unsafe { llvm::LLVMRustDIBuilderCreateNameSpace( DIB(ccx), parent_scope, namespace_name.as_ptr(), - file, - line as c_uint) + unknown_file_metadata(ccx), + UNKNOWN_LINE_NUMBER) }; debug_context(ccx).namespace_map.borrow_mut().insert(def_id, scope); diff --git a/src/librustc_trans/debuginfo/utils.rs b/src/librustc_trans/debuginfo/utils.rs index 0a873767d9359..0555714d623e6 100644 --- a/src/librustc_trans/debuginfo/utils.rs +++ b/src/librustc_trans/debuginfo/utils.rs @@ -73,13 +73,7 @@ pub fn DIB(cx: &CrateContext) -> DIBuilderRef { cx.dbg_cx().as_ref().unwrap().builder } -pub fn get_namespace_and_span_for_item(cx: &CrateContext, def_id: DefId) - -> (DIScope, Span) { - let containing_scope = item_namespace(cx, cx.tcx().parent(def_id) - .expect("get_namespace_and_span_for_item: missing parent?")); - - // Try to get some span information, if we have an inlined item. - let definition_span = cx.tcx().def_span(def_id); - - (containing_scope, definition_span) +pub fn get_namespace_for_item(cx: &CrateContext, def_id: DefId) -> DIScope { + item_namespace(cx, cx.tcx().parent(def_id) + .expect("get_namespace_for_item: missing parent?")) } diff --git a/src/test/incremental/spans_in_type_debuginfo.rs b/src/test/incremental/spans_in_type_debuginfo.rs new file mode 100644 index 0000000000000..7d8e6c9d9d7ef --- /dev/null +++ b/src/test/incremental/spans_in_type_debuginfo.rs @@ -0,0 +1,63 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test that moving a type definition within a source file does not affect +// re-compilation. + +// revisions:rpass1 rpass2 +// compile-flags: -Z query-dep-graph -g + +#![rustc_partition_reused(module="spans_in_type_debuginfo", cfg="rpass2")] +#![rustc_partition_reused(module="spans_in_type_debuginfo-structs", cfg="rpass2")] +#![rustc_partition_reused(module="spans_in_type_debuginfo-enums", cfg="rpass2")] + +#![feature(rustc_attrs)] + +mod structs { + #[cfg(rpass1)] + pub struct X { + pub x: u32, + } + + #[cfg(rpass2)] + pub struct X { + pub x: u32, + } + + pub fn foo(x: X) -> u32 { + x.x + } +} + +mod enums { + #[cfg(rpass1)] + pub enum X { + A { x: u32 }, + B(u32), + } + + #[cfg(rpass2)] + pub enum X { + A { x: u32 }, + B(u32), + } + + pub fn foo(x: X) -> u32 { + match x { + X::A { x } => x, + X::B(x) => x, + } + } +} + +pub fn main() { + let _ = structs::foo(structs::X { x: 1 }); + let _ = enums::foo(enums::X::A { x: 2 }); +}