Skip to content

Commit ef583eb

Browse files
committed
Fix delegation def path hash collision
1 parent fd0c901 commit ef583eb

14 files changed

Lines changed: 280 additions & 67 deletions

File tree

compiler/rustc_ast_lowering/src/delegation.rs

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,26 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
153153
&mut self,
154154
delegation: &Delegation,
155155
item_id: NodeId,
156+
item_span: Span,
156157
) -> DelegationResults<'hir> {
157-
let span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
158+
let last_seg_span = self.lower_span(delegation.path.segments.last().unwrap().ident.span);
159+
let item_span = self.lower_span(item_span);
160+
161+
// Check if the span of the last segment is contained in item span. The span of last segment
162+
// may refer to completely different entity, for example when we do a glob reuse we
163+
// generate segments (in `rustc_expand::expand::build_single_delegations`),
164+
// and during `rustc_resolve::macros::glob_delegation_suffixes` we generate
165+
// suffixes, where identifiers that are used in generated segment
166+
// use spans of the original functions from trait,
167+
// thus those spans can point either to local or external
168+
// trait functions. This `span` is also used for diagnostics purposes, so we want it to point
169+
// to delegation, not to the random trait function, so we perform this check here.
170+
// We could have added similar check in `rustc_resolve::macros::glob_delegation_suffixes`
171+
// (i.e. create ident with span related to ast path of delegation, not the original trait item),
172+
// or in `rustc_expand::expand::build_single_delegations`,
173+
// however it will break `impl-reuse-pass` test and checking span here seems to be good solution,
174+
// as bad spans may come from different places in future.
175+
let span = if item_span.contains(last_seg_span) { last_seg_span } else { item_span };
158176

159177
// Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356)
160178
let ids = if let Some(delegation_info) =
@@ -651,7 +669,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
651669

652670
// FIXME(fn_delegation): proper support for parent generics propagation
653671
// in method call scenario.
654-
let segment = self.process_segment(item_id, span, &segment, &mut generics.child, false);
672+
let segment = self.process_segment(item_id, span, &segment, &mut generics.child, true);
655673
let segment = self.arena.alloc(segment);
656674

657675
self.arena.alloc(hir::Expr {
@@ -677,14 +695,14 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
677695

678696
new_path.segments = self.arena.alloc_from_iter(
679697
new_path.segments.iter().enumerate().map(|(idx, segment)| {
680-
let mut process_segment = |result, add_lifetimes| {
681-
self.process_segment(item_id, span, segment, result, add_lifetimes)
698+
let mut process_segment = |result, is_child| {
699+
self.process_segment(item_id, span, segment, result, is_child)
682700
};
683701

684702
if idx + 2 == len {
685-
process_segment(&mut generics.parent, true)
703+
process_segment(&mut generics.parent, false)
686704
} else if idx + 1 == len {
687-
process_segment(&mut generics.child, false)
705+
process_segment(&mut generics.child, true)
688706
} else {
689707
segment.clone()
690708
}
@@ -695,7 +713,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
695713
}
696714
hir::QPath::TypeRelative(ty, segment) => {
697715
let segment =
698-
self.process_segment(item_id, span, segment, &mut generics.child, false);
716+
self.process_segment(item_id, span, segment, &mut generics.child, true);
699717

700718
hir::QPath::TypeRelative(ty, self.arena.alloc(segment))
701719
}
@@ -723,17 +741,17 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
723741
span: Span,
724742
segment: &hir::PathSegment<'hir>,
725743
result: &mut GenericsGenerationResult<'hir>,
726-
add_lifetimes: bool,
744+
is_child_segment: bool,
727745
) -> hir::PathSegment<'hir> {
728746
let details = result.generics.args_propagation_details();
729747

730748
// The first condition is needed when there is SelfAndUserSpecified case,
731749
// we don't want to propagate generics params in this situation.
732-
let segment = if details.should_propagate
750+
let mut segment = if details.should_propagate
733751
&& let Some(args) = result
734752
.generics
735753
.into_hir_generics(self, item_id, span)
736-
.into_generic_args(self, add_lifetimes, span)
754+
.into_generic_args(self, !is_child_segment, span)
737755
{
738756
hir::PathSegment { args: Some(args), ..segment.clone() }
739757
} else {
@@ -744,6 +762,12 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
744762
result.args_segment_id = Some(segment.hir_id);
745763
}
746764

765+
// Update segment ident span if it is not contained in delegation span, see comment
766+
// in `lower_delegation` function in this file.
767+
if is_child_segment && !span.contains(segment.ident.span) {
768+
segment.ident.span = span;
769+
}
770+
747771
segment
748772
}
749773

compiler/rustc_ast_lowering/src/delegation/generics.rs

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use hir::def::{DefKind, Res};
33
use rustc_ast::*;
44
use rustc_hir as hir;
55
use rustc_hir::def_id::DefId;
6+
use rustc_hir::definitions::{DefPathData, DelegationDefPathKind};
67
use rustc_middle::ty::GenericParamDefKind;
78
use rustc_middle::{bug, ty};
89
use rustc_span::sym::{self};
@@ -332,20 +333,27 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
332333
GenericParamKind::Const { default, .. } => *default = None,
333334
}
334335

336+
let name = p.ident.name;
337+
let kind = match p.kind {
338+
GenericParamKind::Lifetime => DelegationDefPathKind::Lifetime,
339+
GenericParamKind::Type { .. } => DelegationDefPathKind::TyParam,
340+
GenericParamKind::Const { .. } => DelegationDefPathKind::ConstParam,
341+
};
342+
335343
// Note that we use self.disambiguator here, if we will create new every time
336344
// we will get ICE if params have the same name.
337345
self.resolver.insert_new_def_id(
338346
p.id,
339347
self.tcx
340348
.create_def(
341349
self.local_def_id(item_id),
342-
Some(p.ident.name),
350+
Some(name),
343351
match p.kind {
344352
GenericParamKind::Lifetime => DefKind::LifetimeParam,
345353
GenericParamKind::Type { .. } => DefKind::TyParam,
346354
GenericParamKind::Const { .. } => DefKind::ConstParam,
347355
},
348-
None,
356+
Some(DefPathData::Delegation { name, kind }),
349357
&mut self.disambiguator,
350358
)
351359
.def_id(),
@@ -439,7 +447,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
439447
res,
440448
}]),
441449
res,
442-
span: p.span,
450+
span,
443451
}),
444452
)
445453
};
@@ -460,15 +468,15 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
460468
hir::GenericParamKind::Type { .. } => {
461469
Some(hir::GenericArg::Type(self.arena.alloc(hir::Ty {
462470
hir_id: self.next_id(),
463-
span: p.span,
471+
span,
464472
kind: hir::TyKind::Path(create_path(self)),
465473
})))
466474
}
467475
hir::GenericParamKind::Const { .. } => {
468476
Some(hir::GenericArg::Const(self.arena.alloc(hir::ConstArg {
469477
hir_id: self.next_id(),
470478
kind: hir::ConstArgKind::Path(create_path(self)),
471-
span: p.span,
479+
span,
472480
})))
473481
}
474482
}
@@ -519,7 +527,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
519527
bounds: Default::default(),
520528
colon_span: None,
521529
id: self.next_node_id(),
522-
ident: Ident::with_dummy_span(p.name),
530+
ident: Ident::new(p.name, span),
523531
is_placeholder: false,
524532
kind: match p.kind {
525533
GenericParamDefKind::Lifetime => GenericParamKind::Lifetime,
@@ -563,18 +571,18 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
563571
None,
564572
Path {
565573
segments: thin_vec![PathSegment {
566-
ident: Ident::with_dummy_span(type_symbol),
574+
ident: Ident::new(type_symbol, span),
567575
id: self.next_node_id(),
568576
args: None
569577
}],
570-
span: DUMMY_SP,
578+
span,
571579
tokens: None,
572580
},
573581
),
574-
span: DUMMY_SP,
582+
span,
575583
tokens: None,
576584
}),
577-
span: DUMMY_SP,
585+
span,
578586
default: None,
579587
}
580588
}
@@ -608,7 +616,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
608616
0,
609617
GenericParam {
610618
id: self.next_node_id(),
611-
ident: Ident::new(kw::SelfUpper, DUMMY_SP),
619+
ident: Ident::new(kw::SelfUpper, span),
612620
attrs: Default::default(),
613621
bounds: vec![],
614622
is_placeholder: false,

compiler/rustc_ast_lowering/src/item.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
579579
hir::ItemKind::Macro(ident, macro_def, macro_kinds)
580580
}
581581
ItemKind::Delegation(box delegation) => {
582-
let delegation_results = self.lower_delegation(delegation, id);
582+
let delegation_results = self.lower_delegation(delegation, id, span);
583583
hir::ItemKind::Fn {
584584
sig: delegation_results.sig,
585585
ident: delegation_results.ident,
@@ -1079,7 +1079,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
10791079
(*ident, generics, kind, ty.is_some())
10801080
}
10811081
AssocItemKind::Delegation(box delegation) => {
1082-
let delegation_results = self.lower_delegation(delegation, i.id);
1082+
let delegation_results = self.lower_delegation(delegation, i.id, i.span);
10831083
let item_kind = hir::TraitItemKind::Fn(
10841084
delegation_results.sig,
10851085
hir::TraitFn::Provided(delegation_results.body_id),
@@ -1272,7 +1272,7 @@ impl<'hir, R: ResolverAstLoweringExt<'hir>> LoweringContext<'_, 'hir, R> {
12721272
)
12731273
}
12741274
AssocItemKind::Delegation(box delegation) => {
1275-
let delegation_results = self.lower_delegation(delegation, i.id);
1275+
let delegation_results = self.lower_delegation(delegation, i.id, i.span);
12761276
(
12771277
delegation.ident,
12781278
(

compiler/rustc_hir/src/definitions.rs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,13 @@ impl DefPath {
269269
}
270270
}
271271

272+
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, BlobDecodable)]
273+
pub enum DelegationDefPathKind {
274+
Lifetime,
275+
ConstParam,
276+
TyParam,
277+
}
278+
272279
/// New variants should only be added in synchronization with `enum DefKind`.
273280
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, BlobDecodable)]
274281
pub enum DefPathData {
@@ -318,6 +325,10 @@ pub enum DefPathData {
318325
SyntheticCoroutineBody,
319326
/// Additional static data referred to by a static.
320327
NestedStatic,
328+
Delegation {
329+
name: Symbol,
330+
kind: DelegationDefPathKind,
331+
},
321332
}
322333

323334
impl Definitions {
@@ -455,8 +466,12 @@ impl DefPathData {
455466
pub fn get_opt_name(&self) -> Option<Symbol> {
456467
use self::DefPathData::*;
457468
match *self {
458-
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
459-
| OpaqueLifetime(name) => Some(name),
469+
TypeNs(name)
470+
| ValueNs(name)
471+
| MacroNs(name)
472+
| LifetimeNs(name)
473+
| OpaqueLifetime(name)
474+
| Delegation { name, .. } => Some(name),
460475

461476
DesugaredAnonymousLifetime => Some(kw::UnderscoreLifetime),
462477

@@ -479,8 +494,13 @@ impl DefPathData {
479494
fn hashed_symbol(&self) -> Option<Symbol> {
480495
use self::DefPathData::*;
481496
match *self {
482-
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name) | AnonAssocTy(name)
483-
| OpaqueLifetime(name) => Some(name),
497+
TypeNs(name)
498+
| ValueNs(name)
499+
| MacroNs(name)
500+
| LifetimeNs(name)
501+
| AnonAssocTy(name)
502+
| OpaqueLifetime(name)
503+
| Delegation { name, .. } => Some(name),
484504

485505
DesugaredAnonymousLifetime => Some(kw::UnderscoreLifetime),
486506

@@ -502,8 +522,12 @@ impl DefPathData {
502522
pub fn name(&self) -> DefPathDataName {
503523
use self::DefPathData::*;
504524
match *self {
505-
TypeNs(name) | ValueNs(name) | MacroNs(name) | LifetimeNs(name)
506-
| OpaqueLifetime(name) => DefPathDataName::Named(name),
525+
TypeNs(name)
526+
| ValueNs(name)
527+
| MacroNs(name)
528+
| LifetimeNs(name)
529+
| OpaqueLifetime(name)
530+
| Delegation { name, .. } => DefPathDataName::Named(name),
507531
// Note that this does not show up in user print-outs.
508532
CrateRoot => DefPathDataName::Anon { namespace: kw::Crate },
509533
Impl => DefPathDataName::Anon { namespace: kw::Impl },

compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::fmt::Write as _;
1010
use rustc_abi::{ExternAbi, Integer};
1111
use rustc_data_structures::base_n::{ALPHANUMERIC_ONLY, CASE_INSENSITIVE, ToBaseN};
1212
use rustc_data_structures::fx::FxHashMap;
13-
use rustc_hir as hir;
13+
use rustc_hir::definitions::{DefPathData, DelegationDefPathKind};
1414
use rustc_hir::find_attr;
1515
use rustc_middle::bug;
1616
use rustc_middle::ty::layout::IntegerExt;
@@ -672,26 +672,33 @@ fn encode_ty_name(tcx: TyCtxt<'_>, def_id: DefId) -> String {
672672
def_path.data.reverse();
673673
for disambiguated_data in &def_path.data {
674674
s.push('N');
675+
676+
const TYPE_NS: &str = "t";
677+
const VALUE_NS: &str = "v";
675678
s.push_str(match disambiguated_data.data {
676-
hir::definitions::DefPathData::Impl => "I", // Not specified in v0's <namespace>
677-
hir::definitions::DefPathData::ForeignMod => "F", // Not specified in v0's <namespace>
678-
hir::definitions::DefPathData::TypeNs(..) => "t",
679-
hir::definitions::DefPathData::ValueNs(..) => "v",
680-
hir::definitions::DefPathData::Closure => "C",
681-
hir::definitions::DefPathData::Ctor => "c",
682-
hir::definitions::DefPathData::AnonConst => "K",
683-
hir::definitions::DefPathData::LateAnonConst => "k",
684-
hir::definitions::DefPathData::OpaqueTy => "i",
685-
hir::definitions::DefPathData::SyntheticCoroutineBody => "s",
686-
hir::definitions::DefPathData::NestedStatic => "n",
687-
hir::definitions::DefPathData::CrateRoot
688-
| hir::definitions::DefPathData::Use
689-
| hir::definitions::DefPathData::GlobalAsm
690-
| hir::definitions::DefPathData::MacroNs(..)
691-
| hir::definitions::DefPathData::OpaqueLifetime(..)
692-
| hir::definitions::DefPathData::LifetimeNs(..)
693-
| hir::definitions::DefPathData::DesugaredAnonymousLifetime
694-
| hir::definitions::DefPathData::AnonAssocTy(..) => {
679+
DefPathData::Impl => "I", // Not specified in v0's <namespace>
680+
DefPathData::ForeignMod => "F", // Not specified in v0's <namespace>
681+
DefPathData::TypeNs(..) => TYPE_NS,
682+
DefPathData::ValueNs(..) => VALUE_NS,
683+
DefPathData::Closure => "C",
684+
DefPathData::Ctor => "c",
685+
DefPathData::AnonConst => "K",
686+
DefPathData::LateAnonConst => "k",
687+
DefPathData::OpaqueTy => "i",
688+
DefPathData::SyntheticCoroutineBody => "s",
689+
DefPathData::NestedStatic => "n",
690+
DefPathData::Delegation { kind: DelegationDefPathKind::ConstParam, .. } => VALUE_NS,
691+
DefPathData::Delegation { kind: DelegationDefPathKind::TyParam, .. } => TYPE_NS,
692+
693+
DefPathData::CrateRoot
694+
| DefPathData::Use
695+
| DefPathData::GlobalAsm
696+
| DefPathData::MacroNs(..)
697+
| DefPathData::OpaqueLifetime(..)
698+
| DefPathData::LifetimeNs(..)
699+
| DefPathData::DesugaredAnonymousLifetime
700+
| DefPathData::AnonAssocTy(..)
701+
| DefPathData::Delegation { kind: DelegationDefPathKind::Lifetime, .. } => {
695702
bug!("encode_ty_name: unexpected `{:?}`", disambiguated_data.data);
696703
}
697704
});

0 commit comments

Comments
 (0)