Skip to content

Commit 455a0e1

Browse files
committed
Use Symbol instead of Ident as an assoc_name to prevent ICEs
An ICE happens when certain code is compiled in incremental compilation mode and there are two `Ident`s that have the same `StableHash` value but are considered different by `Eq` and `Hash`.
1 parent 03c0e58 commit 455a0e1

File tree

9 files changed

+77
-23
lines changed

9 files changed

+77
-23
lines changed

compiler/rustc_infer/src/traits/util.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::traits::{Obligation, ObligationCause, PredicateObligation};
44
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
55
use rustc_middle::ty::outlives::Component;
66
use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
7-
use rustc_span::symbol::Ident;
7+
use rustc_span::symbol::Symbol;
88

99
pub fn anonymize_predicate<'tcx>(
1010
tcx: TyCtxt<'tcx>,
@@ -296,7 +296,7 @@ pub fn transitive_bounds<'tcx>(
296296
pub fn transitive_bounds_that_define_assoc_type<'tcx>(
297297
tcx: TyCtxt<'tcx>,
298298
bounds: impl Iterator<Item = ty::PolyTraitRef<'tcx>>,
299-
assoc_name: Ident,
299+
assoc_name: Symbol,
300300
) -> FxIndexSet<ty::PolyTraitRef<'tcx>> {
301301
let mut stack: Vec<_> = bounds.collect();
302302
let mut trait_refs = FxIndexSet::default();

compiler/rustc_middle/src/query/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -451,11 +451,11 @@ rustc_queries! {
451451
desc { |tcx| "computing the super predicates of `{}`", tcx.def_path_str(key) }
452452
}
453453

454-
/// The `Option<Ident>` is the name of an associated type. If it is `None`, then this query
455-
/// returns the full set of predicates. If `Some<Ident>`, then the query returns only the
454+
/// The `Option<Symbol>` is the name of an associated type. If it is `None`, then this query
455+
/// returns the full set of predicates. If `Some<Symbol>`, then the query returns only the
456456
/// subset of super-predicates that reference traits that define the given associated type.
457457
/// This is used to avoid cycles in resolving types like `T::Item`.
458-
query super_predicates_that_define_assoc_type(key: (DefId, Option<rustc_span::symbol::Ident>)) -> ty::GenericPredicates<'tcx> {
458+
query super_predicates_that_define_assoc_type(key: (DefId, Option<rustc_span::symbol::Symbol>)) -> ty::GenericPredicates<'tcx> {
459459
desc { |tcx| "computing the super traits of `{}`{}",
460460
tcx.def_path_str(key.0),
461461
if let Some(assoc_name) = key.1 { format!(" with associated type name `{}`", assoc_name) } else { "".to_string() },
@@ -464,7 +464,7 @@ rustc_queries! {
464464

465465
/// To avoid cycles within the predicates of a single item we compute
466466
/// per-type-parameter predicates for resolving `T::AssocTy`.
467-
query type_param_predicates(key: (DefId, LocalDefId, rustc_span::symbol::Ident)) -> ty::GenericPredicates<'tcx> {
467+
query type_param_predicates(key: (DefId, LocalDefId, rustc_span::symbol::Symbol)) -> ty::GenericPredicates<'tcx> {
468468
desc { |tcx| "computing the bounds for type parameter `{}`", {
469469
let id = tcx.hir().local_def_id_to_hir_id(key.1);
470470
tcx.hir().ty_param_name(id)

compiler/rustc_middle/src/ty/context.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
5151
use rustc_session::lint::{Level, Lint};
5252
use rustc_session::Session;
5353
use rustc_span::source_map::MultiSpan;
54-
use rustc_span::symbol::{kw, sym, Ident, Symbol};
54+
use rustc_span::symbol::{kw, sym, Symbol};
5555
use rustc_span::{Span, DUMMY_SP};
5656
use rustc_target::abi::{Layout, TargetDataLayout, VariantIdx};
5757
use rustc_target::spec::abi;
@@ -2083,10 +2083,11 @@ impl<'tcx> TyCtxt<'tcx> {
20832083

20842084
/// Given the def_id of a Trait `trait_def_id` and the name of an associated item `assoc_name`
20852085
/// returns true if the `trait_def_id` defines an associated item of name `assoc_name`.
2086-
pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Ident) -> bool {
2086+
pub fn trait_may_define_assoc_type(self, trait_def_id: DefId, assoc_name: Symbol) -> bool {
20872087
self.super_traits_of(trait_def_id).any(|trait_did| {
20882088
self.associated_items(trait_did)
2089-
.find_by_name_and_kind(self, assoc_name, ty::AssocKind::Type, trait_did)
2089+
.find_by_name_and_kind_unhygienic(assoc_name, ty::AssocKind::Type)
2090+
.next()
20902091
.is_some()
20912092
})
20922093
}

compiler/rustc_middle/src/ty/mod.rs

+10
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,16 @@ impl<'tcx> AssociatedItems<'tcx> {
318318
.find(|item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
319319
}
320320

321+
/// Returns the associated item with the given name and `AssocKind`, if one exists, ignoring
322+
/// hygiene.
323+
pub fn find_by_name_and_kind_unhygienic(
324+
&self,
325+
name: Symbol,
326+
kind: AssocKind,
327+
) -> impl '_ + Iterator<Item = &ty::AssocItem> {
328+
self.filter_by_name_unhygienic(name).filter(move |item| item.kind == kind)
329+
}
330+
321331
/// Returns the associated item with the given name in the given `Namespace`, if one exists.
322332
pub fn find_by_name_and_namespace(
323333
&self,

compiler/rustc_middle/src/ty/query/keys.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use crate::ty::subst::{GenericArg, SubstsRef};
77
use crate::ty::{self, Ty, TyCtxt};
88
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId, LOCAL_CRATE};
99
use rustc_query_system::query::DefaultCacheSelector;
10-
use rustc_span::symbol::{Ident, Symbol};
10+
use rustc_span::symbol::Symbol;
1111
use rustc_span::{Span, DUMMY_SP};
1212

1313
/// The `Key` trait controls what types can legally be used as the key
@@ -149,7 +149,7 @@ impl Key for (LocalDefId, DefId) {
149149
}
150150
}
151151

152-
impl Key for (DefId, Option<Ident>) {
152+
impl Key for (DefId, Option<Symbol>) {
153153
type CacheSelector = DefaultCacheSelector;
154154

155155
fn query_crate(&self) -> CrateNum {
@@ -160,7 +160,7 @@ impl Key for (DefId, Option<Ident>) {
160160
}
161161
}
162162

163-
impl Key for (DefId, LocalDefId, Ident) {
163+
impl Key for (DefId, LocalDefId, Symbol) {
164164
type CacheSelector = DefaultCacheSelector;
165165

166166
fn query_crate(&self) -> CrateNum {

compiler/rustc_typeck/src/astconv/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ pub trait AstConv<'tcx> {
6565
&self,
6666
span: Span,
6767
def_id: DefId,
68-
assoc_name: Ident,
68+
assoc_name: Symbol,
6969
) -> ty::GenericPredicates<'tcx>;
7070

7171
/// Returns the lifetime to use when a lifetime is omitted (and not elided).
@@ -887,7 +887,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
887887
ast_bounds: &[hir::GenericBound<'_>],
888888
sized_by_default: SizedByDefault,
889889
span: Span,
890-
assoc_name: Ident,
890+
assoc_name: Symbol,
891891
) -> Bounds<'tcx> {
892892
let mut result = Vec::new();
893893

@@ -1398,7 +1398,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
13981398
);
13991399

14001400
let predicates = &self
1401-
.get_type_parameter_bounds(span, ty_param_def_id.to_def_id(), assoc_name)
1401+
.get_type_parameter_bounds(span, ty_param_def_id.to_def_id(), assoc_name.name)
14021402
.predicates;
14031403

14041404
debug!("find_bound_for_assoc_item: predicates={:#?}", predicates);
@@ -1412,7 +1412,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
14121412
predicates.iter().filter_map(|(p, _)| {
14131413
p.to_opt_poly_trait_ref().map(|trait_ref| trait_ref.value)
14141414
}),
1415-
assoc_name,
1415+
assoc_name.name,
14161416
)
14171417
.into_iter()
14181418
},

compiler/rustc_typeck/src/check/fn_ctxt/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_middle::ty::fold::TypeFoldable;
2020
use rustc_middle::ty::subst::GenericArgKind;
2121
use rustc_middle::ty::{self, Const, Ty, TyCtxt};
2222
use rustc_session::Session;
23-
use rustc_span::symbol::Ident;
23+
use rustc_span::symbol::Symbol;
2424
use rustc_span::{self, Span};
2525
use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode};
2626

@@ -188,7 +188,7 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
188188
&self,
189189
_: Span,
190190
def_id: DefId,
191-
_: Ident,
191+
_: Symbol,
192192
) -> ty::GenericPredicates<'tcx> {
193193
let tcx = self.tcx;
194194
let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local());

compiler/rustc_typeck/src/collect.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> {
316316
&self,
317317
span: Span,
318318
def_id: DefId,
319-
assoc_name: Ident,
319+
assoc_name: Symbol,
320320
) -> ty::GenericPredicates<'tcx> {
321321
self.tcx.at(span).type_param_predicates((
322322
self.item_def_id,
@@ -503,7 +503,7 @@ fn get_new_lifetime_name<'tcx>(
503503
/// `X: Foo` where `X` is the type parameter `def_id`.
504504
fn type_param_predicates(
505505
tcx: TyCtxt<'_>,
506-
(item_def_id, def_id, assoc_name): (DefId, LocalDefId, Ident),
506+
(item_def_id, def_id, assoc_name): (DefId, LocalDefId, Symbol),
507507
) -> ty::GenericPredicates<'_> {
508508
use rustc_hir::*;
509509

@@ -600,7 +600,7 @@ impl ItemCtxt<'tcx> {
600600
param_id: hir::HirId,
601601
ty: Ty<'tcx>,
602602
only_self_bounds: OnlySelfBounds,
603-
assoc_name: Option<Ident>,
603+
assoc_name: Option<Symbol>,
604604
) -> Vec<(ty::Predicate<'tcx>, Span)> {
605605
let constness = self.default_constness_for_trait_bounds();
606606
let from_ty_params = ast_generics
@@ -646,7 +646,7 @@ impl ItemCtxt<'tcx> {
646646
from_ty_params.chain(from_where_clauses).collect()
647647
}
648648

649-
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Ident) -> bool {
649+
fn bound_defines_assoc_item(&self, b: &hir::GenericBound<'_>, assoc_name: Symbol) -> bool {
650650
debug!("bound_defines_assoc_item(b={:?}, assoc_name={:?})", b, assoc_name);
651651

652652
match b {
@@ -1037,7 +1037,7 @@ fn super_predicates_of(tcx: TyCtxt<'_>, trait_def_id: DefId) -> ty::GenericPredi
10371037
/// the transitive super-predicates are converted.
10381038
fn super_predicates_that_define_assoc_type(
10391039
tcx: TyCtxt<'_>,
1040-
(trait_def_id, assoc_name): (DefId, Option<Ident>),
1040+
(trait_def_id, assoc_name): (DefId, Option<Symbol>),
10411041
) -> ty::GenericPredicates<'_> {
10421042
debug!(
10431043
"super_predicates_that_define_assoc_type(trait_def_id={:?}, assoc_name={:?})",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// check-pass
2+
// compile-flags:-Cincremental=tmp/traits-assoc-type-macros
3+
4+
// This test case makes sure that we can compile with incremental compilation
5+
// enabled when there are macros, traits, inheritance and associated types involved.
6+
7+
trait Deserializer {
8+
type Error;
9+
}
10+
11+
trait Deserialize {
12+
fn deserialize<D>(_: D) -> D::Error
13+
where
14+
D: Deserializer;
15+
}
16+
17+
macro_rules! impl_deserialize {
18+
($name:ident) => {
19+
impl Deserialize for $name {
20+
fn deserialize<D>(_: D) -> D::Error
21+
where
22+
D: Deserializer,
23+
{
24+
loop {}
25+
}
26+
}
27+
};
28+
}
29+
30+
macro_rules! formats {
31+
{
32+
$($name:ident,)*
33+
} => {
34+
$(
35+
pub struct $name;
36+
37+
impl_deserialize!($name);
38+
)*
39+
}
40+
}
41+
formats! { Foo, Bar, }
42+
43+
fn main() {}

0 commit comments

Comments
 (0)