Skip to content

Commit 16ec1c0

Browse files
committed
Auto merge of rust-lang#111776 - cuviper:beta-next, r=cuviper
[beta] backport - debuginfo: split method declaration and definition rust-lang#111167 - Encode VariantIdx so we can decode ADT variants in the right order rust-lang#111494 - Simplify find_width_of_character_at_span. rust-lang#111560 r? cuviper
2 parents 2013813 + 7a0af09 commit 16ec1c0

File tree

12 files changed

+181
-85
lines changed

12 files changed

+181
-85
lines changed

compiler/rustc_codegen_llvm/src/debuginfo/mod.rs

+52-34
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
321321
let tcx = self.tcx;
322322

323323
let def_id = instance.def_id();
324-
let containing_scope = get_containing_scope(self, instance);
324+
let (containing_scope, is_method) = get_containing_scope(self, instance);
325325
let span = tcx.def_span(def_id);
326326
let loc = self.lookup_debug_loc(span.lo());
327327
let file_metadata = file_metadata(self, &loc.file);
@@ -377,8 +377,29 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
377377
}
378378
}
379379

380-
unsafe {
381-
return llvm::LLVMRustDIBuilderCreateFunction(
380+
// When we're adding a method to a type DIE, we only want a DW_AT_declaration there, because
381+
// LLVM LTO can't unify type definitions when a child DIE is a full subprogram definition.
382+
// When we use this `decl` below, the subprogram definition gets created at the CU level
383+
// with a DW_AT_specification pointing back to the type's declaration.
384+
let decl = is_method.then(|| unsafe {
385+
llvm::LLVMRustDIBuilderCreateMethod(
386+
DIB(self),
387+
containing_scope,
388+
name.as_ptr().cast(),
389+
name.len(),
390+
linkage_name.as_ptr().cast(),
391+
linkage_name.len(),
392+
file_metadata,
393+
loc.line,
394+
function_type_metadata,
395+
flags,
396+
spflags & !DISPFlags::SPFlagDefinition,
397+
template_parameters,
398+
)
399+
});
400+
401+
return unsafe {
402+
llvm::LLVMRustDIBuilderCreateFunction(
382403
DIB(self),
383404
containing_scope,
384405
name.as_ptr().cast(),
@@ -393,9 +414,9 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
393414
spflags,
394415
maybe_definition_llfn,
395416
template_parameters,
396-
None,
397-
);
398-
}
417+
decl,
418+
)
419+
};
399420

400421
fn get_function_signature<'ll, 'tcx>(
401422
cx: &CodegenCx<'ll, 'tcx>,
@@ -494,14 +515,16 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
494515
names
495516
}
496517

518+
/// Returns a scope, plus `true` if that's a type scope for "class" methods,
519+
/// otherwise `false` for plain namespace scopes.
497520
fn get_containing_scope<'ll, 'tcx>(
498521
cx: &CodegenCx<'ll, 'tcx>,
499522
instance: Instance<'tcx>,
500-
) -> &'ll DIScope {
523+
) -> (&'ll DIScope, bool) {
501524
// First, let's see if this is a method within an inherent impl. Because
502525
// if yes, we want to make the result subroutine DIE a child of the
503526
// subroutine's self-type.
504-
let self_type = cx.tcx.impl_of_method(instance.def_id()).and_then(|impl_def_id| {
527+
if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) {
505528
// If the method does *not* belong to a trait, proceed
506529
if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
507530
let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
@@ -512,39 +535,34 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
512535

513536
// Only "class" methods are generally understood by LLVM,
514537
// so avoid methods on other types (e.g., `<*mut T>::null`).
515-
match impl_self_ty.kind() {
516-
ty::Adt(def, ..) if !def.is_box() => {
517-
// Again, only create type information if full debuginfo is enabled
518-
if cx.sess().opts.debuginfo == DebugInfo::Full
519-
&& !impl_self_ty.needs_subst()
520-
{
521-
Some(type_di_node(cx, impl_self_ty))
522-
} else {
523-
Some(namespace::item_namespace(cx, def.did()))
524-
}
538+
if let ty::Adt(def, ..) = impl_self_ty.kind() && !def.is_box() {
539+
// Again, only create type information if full debuginfo is enabled
540+
if cx.sess().opts.debuginfo == DebugInfo::Full
541+
&& !impl_self_ty.needs_subst()
542+
{
543+
return (type_di_node(cx, impl_self_ty), true);
544+
} else {
545+
return (namespace::item_namespace(cx, def.did()), false);
525546
}
526-
_ => None,
527547
}
528548
} else {
529549
// For trait method impls we still use the "parallel namespace"
530550
// strategy
531-
None
532551
}
533-
});
552+
}
534553

535-
self_type.unwrap_or_else(|| {
536-
namespace::item_namespace(
537-
cx,
538-
DefId {
539-
krate: instance.def_id().krate,
540-
index: cx
541-
.tcx
542-
.def_key(instance.def_id())
543-
.parent
544-
.expect("get_containing_scope: missing parent?"),
545-
},
546-
)
547-
})
554+
let scope = namespace::item_namespace(
555+
cx,
556+
DefId {
557+
krate: instance.def_id().krate,
558+
index: cx
559+
.tcx
560+
.def_key(instance.def_id())
561+
.parent
562+
.expect("get_containing_scope: missing parent?"),
563+
},
564+
);
565+
(scope, false)
548566
}
549567
}
550568

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+15
Original file line numberDiff line numberDiff line change
@@ -1986,6 +1986,21 @@ extern "C" {
19861986
Decl: Option<&'a DIDescriptor>,
19871987
) -> &'a DISubprogram;
19881988

1989+
pub fn LLVMRustDIBuilderCreateMethod<'a>(
1990+
Builder: &DIBuilder<'a>,
1991+
Scope: &'a DIDescriptor,
1992+
Name: *const c_char,
1993+
NameLen: size_t,
1994+
LinkageName: *const c_char,
1995+
LinkageNameLen: size_t,
1996+
File: &'a DIFile,
1997+
LineNo: c_uint,
1998+
Ty: &'a DIType,
1999+
Flags: DIFlags,
2000+
SPFlags: DISPFlags,
2001+
TParam: &'a DIArray,
2002+
) -> &'a DISubprogram;
2003+
19892004
pub fn LLVMRustDIBuilderCreateBasicType<'a>(
19902005
Builder: &DIBuilder<'a>,
19912006
Name: *const c_char,

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,28 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateFunction(
831831
return wrap(Sub);
832832
}
833833

834+
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateMethod(
835+
LLVMRustDIBuilderRef Builder, LLVMMetadataRef Scope,
836+
const char *Name, size_t NameLen,
837+
const char *LinkageName, size_t LinkageNameLen,
838+
LLVMMetadataRef File, unsigned LineNo,
839+
LLVMMetadataRef Ty, LLVMRustDIFlags Flags,
840+
LLVMRustDISPFlags SPFlags, LLVMMetadataRef TParam) {
841+
DITemplateParameterArray TParams =
842+
DITemplateParameterArray(unwrap<MDTuple>(TParam));
843+
DISubprogram::DISPFlags llvmSPFlags = fromRust(SPFlags);
844+
DINode::DIFlags llvmFlags = fromRust(Flags);
845+
DISubprogram *Sub = Builder->createMethod(
846+
unwrapDI<DIScope>(Scope),
847+
StringRef(Name, NameLen),
848+
StringRef(LinkageName, LinkageNameLen),
849+
unwrapDI<DIFile>(File), LineNo,
850+
unwrapDI<DISubroutineType>(Ty),
851+
0, 0, nullptr, // VTable params aren't used
852+
llvmFlags, llvmSPFlags, TParams);
853+
return wrap(Sub);
854+
}
855+
834856
extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateBasicType(
835857
LLVMRustDIBuilderRef Builder, const char *Name, size_t NameLen,
836858
uint64_t SizeInBits, unsigned Encoding) {

compiler/rustc_metadata/src/rmeta/decoder.rs

+41-26
Original file line numberDiff line numberDiff line change
@@ -857,7 +857,12 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
857857
)
858858
}
859859

860-
fn get_variant(self, kind: &DefKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef {
860+
fn get_variant(
861+
self,
862+
kind: DefKind,
863+
index: DefIndex,
864+
parent_did: DefId,
865+
) -> (VariantIdx, ty::VariantDef) {
861866
let adt_kind = match kind {
862867
DefKind::Variant => ty::AdtKind::Enum,
863868
DefKind::Struct => ty::AdtKind::Struct,
@@ -871,27 +876,30 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
871876
if adt_kind == ty::AdtKind::Enum { Some(self.local_def_id(index)) } else { None };
872877
let ctor = data.ctor.map(|(kind, index)| (kind, self.local_def_id(index)));
873878

874-
ty::VariantDef::new(
875-
self.item_name(index),
876-
variant_did,
877-
ctor,
878-
data.discr,
879-
self.root
880-
.tables
881-
.children
882-
.get(self, index)
883-
.expect("fields are not encoded for a variant")
884-
.decode(self)
885-
.map(|index| ty::FieldDef {
886-
did: self.local_def_id(index),
887-
name: self.item_name(index),
888-
vis: self.get_visibility(index),
889-
})
890-
.collect(),
891-
adt_kind,
892-
parent_did,
893-
false,
894-
data.is_non_exhaustive,
879+
(
880+
data.idx,
881+
ty::VariantDef::new(
882+
self.item_name(index),
883+
variant_did,
884+
ctor,
885+
data.discr,
886+
self.root
887+
.tables
888+
.children
889+
.get(self, index)
890+
.expect("fields are not encoded for a variant")
891+
.decode(self)
892+
.map(|index| ty::FieldDef {
893+
did: self.local_def_id(index),
894+
name: self.item_name(index),
895+
vis: self.get_visibility(index),
896+
})
897+
.collect(),
898+
adt_kind,
899+
parent_did,
900+
false,
901+
data.is_non_exhaustive,
902+
),
895903
)
896904
}
897905

@@ -907,7 +915,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
907915
};
908916
let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self);
909917

910-
let variants = if let ty::AdtKind::Enum = adt_kind {
918+
let mut variants: Vec<_> = if let ty::AdtKind::Enum = adt_kind {
911919
self.root
912920
.tables
913921
.children
@@ -918,15 +926,22 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
918926
let kind = self.def_kind(index);
919927
match kind {
920928
DefKind::Ctor(..) => None,
921-
_ => Some(self.get_variant(&kind, index, did)),
929+
_ => Some(self.get_variant(kind, index, did)),
922930
}
923931
})
924932
.collect()
925933
} else {
926-
std::iter::once(self.get_variant(&kind, item_id, did)).collect()
934+
std::iter::once(self.get_variant(kind, item_id, did)).collect()
927935
};
928936

929-
tcx.mk_adt_def(did, adt_kind, variants, repr)
937+
variants.sort_by_key(|(idx, _)| *idx);
938+
939+
tcx.mk_adt_def(
940+
did,
941+
adt_kind,
942+
variants.into_iter().map(|(_, variant)| variant).collect(),
943+
repr,
944+
)
930945
}
931946

932947
fn get_visibility(self, id: DefIndex) -> Visibility<DefId> {

compiler/rustc_metadata/src/rmeta/encoder.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1376,9 +1376,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
13761376
// Therefore, the loop over variants will encode its fields as the adt's children.
13771377
}
13781378

1379-
for variant in adt_def.variants().iter() {
1379+
for (idx, variant) in adt_def.variants().iter_enumerated() {
13801380
let data = VariantData {
13811381
discr: variant.discr,
1382+
idx,
13821383
ctor: variant.ctor.map(|(kind, def_id)| (kind, def_id.index)),
13831384
is_non_exhaustive: variant.is_field_list_non_exhaustive(),
13841385
};

compiler/rustc_metadata/src/rmeta/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ use rustc_span::edition::Edition;
3131
use rustc_span::hygiene::{ExpnIndex, MacroKind};
3232
use rustc_span::symbol::{Ident, Symbol};
3333
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
34+
use rustc_target::abi::VariantIdx;
3435
use rustc_target::spec::{PanicStrategy, TargetTriple};
3536

3637
use std::marker::PhantomData;
@@ -423,6 +424,7 @@ define_tables! {
423424

424425
#[derive(TyEncodable, TyDecodable)]
425426
struct VariantData {
427+
idx: VariantIdx,
426428
discr: ty::VariantDiscr,
427429
/// If this is unit or tuple-variant/struct, then this is the index of the ctor id.
428430
ctor: Option<(CtorKind, DefIndex)>,

compiler/rustc_span/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#![feature(min_specialization)]
2121
#![feature(rustc_attrs)]
2222
#![feature(let_chains)]
23+
#![feature(round_char_boundary)]
2324
#![deny(rustc::untranslatable_diagnostic)]
2425
#![deny(rustc::diagnostic_outside_of_impl)]
2526

compiler/rustc_span/src/source_map.rs

+7-24
Original file line numberDiff line numberDiff line change
@@ -1019,36 +1019,19 @@ impl SourceMap {
10191019

10201020
let src = local_begin.sf.external_src.borrow();
10211021

1022-
// We need to extend the snippet to the end of the src rather than to end_index so when
1023-
// searching forwards for boundaries we've got somewhere to search.
1024-
let snippet = if let Some(ref src) = local_begin.sf.src {
1025-
&src[start_index..]
1022+
let snippet = if let Some(src) = &local_begin.sf.src {
1023+
src
10261024
} else if let Some(src) = src.get_source() {
1027-
&src[start_index..]
1025+
src
10281026
} else {
10291027
return 1;
10301028
};
1031-
debug!("snippet=`{:?}`", snippet);
10321029

1033-
let mut target = if forwards { end_index + 1 } else { end_index - 1 };
1034-
debug!("initial target=`{:?}`", target);
1035-
1036-
while !snippet.is_char_boundary(target - start_index) && target < source_len {
1037-
target = if forwards {
1038-
target + 1
1039-
} else {
1040-
match target.checked_sub(1) {
1041-
Some(target) => target,
1042-
None => {
1043-
break;
1044-
}
1045-
}
1046-
};
1047-
debug!("target=`{:?}`", target);
1030+
if forwards {
1031+
(snippet.ceil_char_boundary(end_index + 1) - end_index) as u32
1032+
} else {
1033+
(end_index - snippet.floor_char_boundary(end_index - 1)) as u32
10481034
}
1049-
debug!("final target=`{:?}`", target);
1050-
1051-
if forwards { (target - end_index) as u32 } else { (end_index - target) as u32 }
10521035
}
10531036

10541037
pub fn get_source_file(&self, filename: &FileName) -> Option<Lrc<SourceFile>> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# ignore-cross-compile
2+
include ../tools.mk
3+
4+
# With the upgrade to LLVM 16, this was getting:
5+
#
6+
# error: Cannot represent a difference across sections
7+
#
8+
# The error stemmed from DI function definitions under type scopes, fixed by
9+
# only declaring in type scope and defining the subprogram elsewhere.
10+
11+
all:
12+
$(RUSTC) lib.rs --test -C lto=fat -C debuginfo=2 -C incremental=$(TMPDIR)/inc-fat
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
extern crate alloc;
2+
3+
#[cfg(test)]
4+
mod tests {
5+
#[test]
6+
fn something_alloc() {
7+
assert_eq!(Vec::<u32>::new(), Vec::<u32>::new());
8+
}
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#[derive(Default)]
2+
pub enum Foo {
3+
A(u32),
4+
#[default]
5+
B,
6+
C(u32),
7+
}

0 commit comments

Comments
 (0)