Skip to content

Commit d798b53

Browse files
committed
Resolve issue #22187 (ICE compiling libcore with RUST_LOG=debug).
The issue is that the Repr logic assumes that any trait_defs to be represented will be non-local. This will not be the case when compiling libcore: the compiler has a default predicate on many types that they will be Sized, and the Sized trait is defined in libcore. If we allow that a Repr'ed trait_def must come from a foreign crate, then, because the Repr logic can be used while the trait_defs table is being built, there will be a chance that a trait_def lookup will fail on Repr. Handle both of these issues by defining a new try_lookup_trait_def for use by the Repr logic that will attempt to look up a trait_def in the local crate, and returns success/failure in an Option<>. Callers are then responsible for making sure the trait_def is actually present in defining the representation.
1 parent 82dcec7 commit d798b53

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

src/librustc/util/ppaux.rs

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -674,12 +674,16 @@ impl<'tcx> UserString<'tcx> for TraitAndProjections<'tcx> {
674674
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
675675
let &(ref trait_ref, ref projection_bounds) = self;
676676
let base = ty::item_path_str(tcx, trait_ref.def_id);
677-
parameterized(tcx,
678-
&base,
679-
trait_ref.substs,
680-
trait_ref.def_id,
681-
&projection_bounds[..],
682-
|| ty::lookup_trait_def(tcx, trait_ref.def_id).generics.clone())
677+
if let Some(trait_def) = try_lookup_trait_def(tcx, trait_ref.def_id) {
678+
parameterized(tcx,
679+
&base,
680+
trait_ref.substs,
681+
trait_ref.def_id,
682+
&projection_bounds[..],
683+
|| trait_def.generics.clone())
684+
} else {
685+
format!("local_trait_not_ready({:?})", trait_ref.def_id)
686+
}
683687
}
684688
}
685689

@@ -807,8 +811,12 @@ impl<'tcx> Repr<'tcx> for ty::TraitRef<'tcx> {
807811
// to enumerate the `for<...>` etc because the debruijn index
808812
// tells you everything you need to know.
809813
let base = ty::item_path_str(tcx, self.def_id);
810-
parameterized(tcx, &base, self.substs, self.def_id, &[],
811-
|| ty::lookup_trait_def(tcx, self.def_id).generics.clone())
814+
if let Some(trait_def) = try_lookup_trait_def(tcx, self.def_id) {
815+
parameterized(tcx, &base, self.substs, self.def_id, &[],
816+
|| trait_def.generics.clone())
817+
} else {
818+
format!("local_trait_not_ready({:?})", self.def_id)
819+
}
812820
}
813821
}
814822

@@ -1275,8 +1283,12 @@ impl<'tcx, T> UserString<'tcx> for ty::Binder<T>
12751283
impl<'tcx> UserString<'tcx> for ty::TraitRef<'tcx> {
12761284
fn user_string(&self, tcx: &ctxt<'tcx>) -> String {
12771285
let path_str = ty::item_path_str(tcx, self.def_id);
1278-
parameterized(tcx, &path_str, self.substs, self.def_id, &[],
1279-
|| ty::lookup_trait_def(tcx, self.def_id).generics.clone())
1286+
if let Some(trait_def) = try_lookup_trait_def(tcx, self.def_id) {
1287+
parameterized(tcx, &path_str, self.substs, self.def_id, &[],
1288+
|| trait_def.generics.clone())
1289+
} else {
1290+
format!("local_trait_not_ready({:?})", self.def_id)
1291+
}
12801292
}
12811293
}
12821294

@@ -1532,3 +1544,16 @@ impl<'tcx> Repr<'tcx> for ast::Unsafety {
15321544
format!("{:?}", *self)
15331545
}
15341546
}
1547+
1548+
// Wrapper around lookup_trait_def that can handle when the trait is
1549+
// defined in the local crate. Returns Option<_> because this function
1550+
// can be called while the trait_defs map is being built, so that
1551+
// looking up the trait_def in the local crate can sometimes fail.
1552+
fn try_lookup_trait_def<'tcx>(tcx: &ctxt<'tcx>, did: ast::DefId)
1553+
-> Option<Rc<ty::TraitDef<'tcx>>> {
1554+
if did.krate == ast::LOCAL_CRATE {
1555+
tcx.trait_defs.borrow().get(&did).map(|r| r.clone())
1556+
} else {
1557+
Some(ty::lookup_trait_def(tcx, did))
1558+
}
1559+
}

0 commit comments

Comments
 (0)