Skip to content

Commit 79395c6

Browse files
authored
Unrolled build for rust-lang#119868
Rollup merge of rust-lang#119868 - oli-obk:unknown_lifetime_ice, r=compiler-errors Register even erroneous impls Otherwise the specialization graph fails to pick it up, even though other code assumes that all impl blocks have an entry in the specialization graph. also includes an unrelated cleanup of the specialization graph query fixes rust-lang#119827
2 parents 2b1365b + 6679e2c commit 79395c6

File tree

9 files changed

+187
-51
lines changed

9 files changed

+187
-51
lines changed

compiler/rustc_middle/src/arena.rs

+1
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ macro_rules! arena_types {
113113
[] stripped_cfg_items: rustc_ast::expand::StrippedCfgItem,
114114
[] mod_child: rustc_middle::metadata::ModChild,
115115
[] features: rustc_feature::Features,
116+
[decode] specialization_graph: rustc_middle::traits::specialization_graph::Graph,
116117
]);
117118
)
118119
}

compiler/rustc_middle/src/query/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -1294,8 +1294,7 @@ rustc_queries! {
12941294
desc { |tcx| "finding trait impls of `{}`", tcx.def_path_str(trait_id) }
12951295
}
12961296

1297-
query specialization_graph_of(trait_id: DefId) -> &'tcx specialization_graph::Graph {
1298-
arena_cache
1297+
query specialization_graph_of(trait_id: DefId) -> Result<&'tcx specialization_graph::Graph, ErrorGuaranteed> {
12991298
desc { |tcx| "building specialization graph of trait `{}`", tcx.def_path_str(trait_id) }
13001299
cache_on_disk_if { true }
13011300
}

compiler/rustc_middle/src/query/on_disk_cache.rs

+9
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,15 @@ impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>> for &'tcx [rustc_ast::InlineAsm
786786
}
787787
}
788788

789+
impl<'a, 'tcx> Decodable<CacheDecoder<'a, 'tcx>>
790+
for &'tcx crate::traits::specialization_graph::Graph
791+
{
792+
#[inline]
793+
fn decode(d: &mut CacheDecoder<'a, 'tcx>) -> Self {
794+
RefDecodable::decode(d)
795+
}
796+
}
797+
789798
macro_rules! impl_ref_decoder {
790799
(<$tcx:tt> $($ty:ty,)*) => {
791800
$(impl<'a, $tcx> Decodable<CacheDecoder<'a, $tcx>> for &$tcx [$ty] {

compiler/rustc_middle/src/traits/specialization_graph.rs

+4-10
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,16 @@ pub struct Graph {
3030

3131
/// The "root" impls are found by looking up the trait's def_id.
3232
pub children: DefIdMap<Children>,
33-
34-
/// Whether an error was emitted while constructing the graph.
35-
pub has_errored: Option<ErrorGuaranteed>,
3633
}
3734

3835
impl Graph {
3936
pub fn new() -> Graph {
40-
Graph { parent: Default::default(), children: Default::default(), has_errored: None }
37+
Graph { parent: Default::default(), children: Default::default() }
4138
}
4239

4340
/// The parent of a given impl, which is the `DefId` of the trait when the
4441
/// impl is a "specialization root".
42+
#[track_caller]
4543
pub fn parent(&self, child: DefId) -> DefId {
4644
*self.parent.get(&child).unwrap_or_else(|| panic!("Failed to get parent for {child:?}"))
4745
}
@@ -255,13 +253,9 @@ pub fn ancestors(
255253
trait_def_id: DefId,
256254
start_from_impl: DefId,
257255
) -> Result<Ancestors<'_>, ErrorGuaranteed> {
258-
let specialization_graph = tcx.specialization_graph_of(trait_def_id);
256+
let specialization_graph = tcx.specialization_graph_of(trait_def_id)?;
259257

260-
if let Some(reported) = specialization_graph.has_errored {
261-
Err(reported)
262-
} else if let Err(reported) =
263-
tcx.type_of(start_from_impl).instantiate_identity().error_reported()
264-
{
258+
if let Err(reported) = tcx.type_of(start_from_impl).instantiate_identity().error_reported() {
265259
Err(reported)
266260
} else {
267261
Ok(Ancestors {

compiler/rustc_middle/src/ty/fast_reject.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ pub enum SimplifiedType {
3232
CoroutineWitness(DefId),
3333
Function(usize),
3434
Placeholder,
35+
Error,
3536
}
3637

3738
/// Generic parameters are pretty much just bound variables, e.g.
@@ -153,7 +154,8 @@ pub fn simplify_type<'tcx>(
153154
TreatParams::ForLookup | TreatParams::AsCandidateKey => None,
154155
},
155156
ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)),
156-
ty::Bound(..) | ty::Infer(_) | ty::Error(_) => None,
157+
ty::Error(_) => Some(SimplifiedType::Error),
158+
ty::Bound(..) | ty::Infer(_) => None,
157159
}
158160
}
159161

compiler/rustc_middle/src/ty/trait_def.rs

-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::traits::specialization_graph;
22
use crate::ty::fast_reject::{self, SimplifiedType, TreatParams, TreatProjections};
3-
use crate::ty::visit::TypeVisitableExt;
43
use crate::ty::{Ident, Ty, TyCtxt};
54
use hir::def_id::LOCAL_CRATE;
65
use rustc_hir as hir;
@@ -241,9 +240,6 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
241240
let impl_def_id = impl_def_id.to_def_id();
242241

243242
let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
244-
if impl_self_ty.references_error() {
245-
continue;
246-
}
247243

248244
if let Some(simplified_self_ty) =
249245
fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsCandidateKey)

compiler/rustc_trait_selection/src/traits/specialize/mod.rs

+34-34
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
2626
use rustc_middle::ty::{GenericArgs, GenericArgsRef};
2727
use rustc_session::lint::builtin::COHERENCE_LEAK_CHECK;
2828
use rustc_session::lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS;
29-
use rustc_span::{Span, DUMMY_SP};
29+
use rustc_span::{ErrorGuaranteed, Span, DUMMY_SP};
3030

3131
use super::util;
3232
use super::SelectionContext;
@@ -258,7 +258,7 @@ fn fulfill_implication<'tcx>(
258258
pub(super) fn specialization_graph_provider(
259259
tcx: TyCtxt<'_>,
260260
trait_id: DefId,
261-
) -> specialization_graph::Graph {
261+
) -> Result<&'_ specialization_graph::Graph, ErrorGuaranteed> {
262262
let mut sg = specialization_graph::Graph::new();
263263
let overlap_mode = specialization_graph::OverlapMode::get(tcx, trait_id);
264264

@@ -271,6 +271,8 @@ pub(super) fn specialization_graph_provider(
271271
trait_impls
272272
.sort_unstable_by_key(|def_id| (-(def_id.krate.as_u32() as i64), def_id.index.index()));
273273

274+
let mut errored = Ok(());
275+
274276
for impl_def_id in trait_impls {
275277
if let Some(impl_def_id) = impl_def_id.as_local() {
276278
// This is where impl overlap checking happens:
@@ -283,15 +285,21 @@ pub(super) fn specialization_graph_provider(
283285
};
284286

285287
if let Some(overlap) = overlap {
286-
report_overlap_conflict(tcx, overlap, impl_def_id, used_to_be_allowed, &mut sg);
288+
errored = errored.and(report_overlap_conflict(
289+
tcx,
290+
overlap,
291+
impl_def_id,
292+
used_to_be_allowed,
293+
));
287294
}
288295
} else {
289296
let parent = tcx.impl_parent(impl_def_id).unwrap_or(trait_id);
290297
sg.record_impl_from_cstore(tcx, parent, impl_def_id)
291298
}
292299
}
300+
errored?;
293301

294-
sg
302+
Ok(tcx.arena.alloc(sg))
295303
}
296304

297305
// This function is only used when
@@ -304,36 +312,31 @@ fn report_overlap_conflict<'tcx>(
304312
overlap: OverlapError<'tcx>,
305313
impl_def_id: LocalDefId,
306314
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
307-
sg: &mut specialization_graph::Graph,
308-
) {
315+
) -> Result<(), ErrorGuaranteed> {
309316
let impl_polarity = tcx.impl_polarity(impl_def_id.to_def_id());
310317
let other_polarity = tcx.impl_polarity(overlap.with_impl);
311318
match (impl_polarity, other_polarity) {
312319
(ty::ImplPolarity::Negative, ty::ImplPolarity::Positive) => {
313-
report_negative_positive_conflict(
320+
Err(report_negative_positive_conflict(
314321
tcx,
315322
&overlap,
316323
impl_def_id,
317324
impl_def_id.to_def_id(),
318325
overlap.with_impl,
319-
sg,
320-
);
326+
))
321327
}
322328

323329
(ty::ImplPolarity::Positive, ty::ImplPolarity::Negative) => {
324-
report_negative_positive_conflict(
330+
Err(report_negative_positive_conflict(
325331
tcx,
326332
&overlap,
327333
impl_def_id,
328334
overlap.with_impl,
329335
impl_def_id.to_def_id(),
330-
sg,
331-
);
336+
))
332337
}
333338

334-
_ => {
335-
report_conflicting_impls(tcx, overlap, impl_def_id, used_to_be_allowed, sg);
336-
}
339+
_ => report_conflicting_impls(tcx, overlap, impl_def_id, used_to_be_allowed),
337340
}
338341
}
339342

@@ -343,25 +346,24 @@ fn report_negative_positive_conflict<'tcx>(
343346
local_impl_def_id: LocalDefId,
344347
negative_impl_def_id: DefId,
345348
positive_impl_def_id: DefId,
346-
sg: &mut specialization_graph::Graph,
347-
) {
348-
let err = tcx.dcx().create_err(NegativePositiveConflict {
349-
impl_span: tcx.def_span(local_impl_def_id),
350-
trait_desc: overlap.trait_ref,
351-
self_ty: overlap.self_ty,
352-
negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
353-
positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
354-
});
355-
sg.has_errored = Some(err.emit());
349+
) -> ErrorGuaranteed {
350+
tcx.dcx()
351+
.create_err(NegativePositiveConflict {
352+
impl_span: tcx.def_span(local_impl_def_id),
353+
trait_desc: overlap.trait_ref,
354+
self_ty: overlap.self_ty,
355+
negative_impl_span: tcx.span_of_impl(negative_impl_def_id),
356+
positive_impl_span: tcx.span_of_impl(positive_impl_def_id),
357+
})
358+
.emit()
356359
}
357360

358361
fn report_conflicting_impls<'tcx>(
359362
tcx: TyCtxt<'tcx>,
360363
overlap: OverlapError<'tcx>,
361364
impl_def_id: LocalDefId,
362365
used_to_be_allowed: Option<FutureCompatOverlapErrorKind>,
363-
sg: &mut specialization_graph::Graph,
364-
) {
366+
) -> Result<(), ErrorGuaranteed> {
365367
let impl_span = tcx.def_span(impl_def_id);
366368

367369
// Work to be done after we've built the DiagnosticBuilder. We have to define it
@@ -429,14 +431,11 @@ fn report_conflicting_impls<'tcx>(
429431
let mut err = tcx.dcx().struct_span_err(impl_span, msg);
430432
err.code(error_code!(E0119));
431433
decorate(tcx, &overlap, impl_span, &mut err);
432-
Some(err.emit())
434+
err.emit()
433435
} else {
434-
Some(
435-
tcx.dcx()
436-
.span_delayed_bug(impl_span, "impl should have failed the orphan check"),
437-
)
436+
tcx.dcx().span_delayed_bug(impl_span, "impl should have failed the orphan check")
438437
};
439-
sg.has_errored = reported;
438+
Err(reported)
440439
}
441440
Some(kind) => {
442441
let lint = match kind {
@@ -452,8 +451,9 @@ fn report_conflicting_impls<'tcx>(
452451
decorate(tcx, &overlap, impl_span, err);
453452
},
454453
);
454+
Ok(())
455455
}
456-
};
456+
}
457457
}
458458

459459
/// Recovers the "impl X for Y" signature from `impl_def_id` and returns it as a
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
trait Foo {
2+
type Context<'c>
3+
where
4+
Self: 'c;
5+
}
6+
7+
impl Foo for Box<dyn Foo> {}
8+
//~^ ERROR `Foo` cannot be made into an object
9+
//~| ERROR `Foo` cannot be made into an object
10+
//~| ERROR cycle detected
11+
//~| ERROR cycle detected
12+
//~| ERROR cycle detected
13+
//~| ERROR the trait bound `Box<(dyn Foo + 'static)>: Foo` is not satisfied
14+
//~| ERROR not all trait items implemented
15+
16+
fn main() {}

0 commit comments

Comments
 (0)