Skip to content

Commit ecdb7bc

Browse files
authored
Rollup merge of #108136 - eggyal:unmet_trait_alias_bound_on_generic_impl, r=compiler-errors
Do not ICE on unmet trait alias impl bounds Fixes #108132 I've also added some documentation to the `impl_def_id` field of `DerivedObligationCause` to try and minimise the risk of such errors in future. r? `@compiler-errors`
2 parents e1e58fc + 55d449f commit ecdb7bc

File tree

10 files changed

+59
-13
lines changed

10 files changed

+59
-13
lines changed

compiler/rustc_hir_typeck/src/fn_ctxt/adjust_fulfillment_errors.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -477,14 +477,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
477477
// This is the "trait" (meaning, the predicate "proved" by this `impl`) which provides the `Self` type we care about.
478478
// For the purposes of this function, we hope that it is a `struct` type, and that our current `expr` is a literal of
479479
// that struct type.
480-
let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_def_id) {
480+
let impl_trait_self_ref = if self.tcx.is_trait_alias(obligation.impl_or_alias_def_id) {
481481
self.tcx.mk_trait_ref(
482-
obligation.impl_def_id,
483-
ty::InternalSubsts::identity_for_item(self.tcx, obligation.impl_def_id),
482+
obligation.impl_or_alias_def_id,
483+
ty::InternalSubsts::identity_for_item(self.tcx, obligation.impl_or_alias_def_id),
484484
)
485485
} else {
486486
self.tcx
487-
.impl_trait_ref(obligation.impl_def_id)
487+
.impl_trait_ref(obligation.impl_or_alias_def_id)
488488
.map(|impl_def| impl_def.skip_binder())
489489
// It is possible that this is absent. In this case, we make no progress.
490490
.ok_or(expr)?
@@ -494,7 +494,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
494494
let impl_self_ty: Ty<'tcx> = impl_trait_self_ref.self_ty();
495495

496496
let impl_predicates: ty::GenericPredicates<'tcx> =
497-
self.tcx.predicates_of(obligation.impl_def_id);
497+
self.tcx.predicates_of(obligation.impl_or_alias_def_id);
498498
let Some(impl_predicate_index) = obligation.impl_def_predicate_index else {
499499
// We don't have the index, so we can only guess.
500500
return Err(expr);

compiler/rustc_hir_typeck/src/method/probe.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1576,7 +1576,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
15761576
traits::ImplDerivedObligation(Box::new(
15771577
traits::ImplDerivedObligationCause {
15781578
derived,
1579-
impl_def_id,
1579+
impl_or_alias_def_id: impl_def_id,
15801580
impl_def_predicate_index: None,
15811581
span,
15821582
},

compiler/rustc_hir_typeck/src/method/suggest.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -616,7 +616,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
616616
ObligationCauseCode::ImplDerivedObligation(data)
617617
if matches!(p.kind().skip_binder(), ty::PredicateKind::Clause(_)) =>
618618
{
619-
Some((p, parent, data.impl_def_id, data))
619+
Some((p, parent, data.impl_or_alias_def_id, data))
620620
}
621621
_ => None,
622622
})
@@ -714,7 +714,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
714714
);
715715
}
716716
Some(Node::Item(hir::Item {
717-
ident, kind: hir::ItemKind::Trait(..), ..
717+
ident,
718+
kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..),
719+
..
718720
})) => {
719721
skip_list.insert(p);
720722
let entry = spanned_predicates.entry(ident.span);

compiler/rustc_infer/src/traits/util.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl<'tcx> Elaborator<'tcx> {
158158
traits::ImplDerivedObligation(Box::new(
159159
traits::ImplDerivedObligationCause {
160160
derived,
161-
impl_def_id: data.def_id(),
161+
impl_or_alias_def_id: data.def_id(),
162162
impl_def_predicate_index: Some(index),
163163
span,
164164
},

compiler/rustc_middle/src/traits/mod.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,11 @@ pub enum WellFormedLoc {
474474
#[derive(TypeVisitable, TypeFoldable)]
475475
pub struct ImplDerivedObligationCause<'tcx> {
476476
pub derived: DerivedObligationCause<'tcx>,
477-
pub impl_def_id: DefId,
477+
/// The `DefId` of the `impl` that gave rise to the `derived` obligation.
478+
/// If the `derived` obligation arose from a trait alias, which conceptually has a synthetic impl,
479+
/// then this will be the `DefId` of that trait alias. Care should therefore be taken to handle
480+
/// that exceptional case where appropriate.
481+
pub impl_or_alias_def_id: DefId,
478482
/// The index of the derived predicate in the parent impl's predicates.
479483
pub impl_def_predicate_index: Option<usize>,
480484
pub span: Span,

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3143,7 +3143,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
31433143
parent_trait_pred.print_modifiers_and_trait_path()
31443144
);
31453145
let mut is_auto_trait = false;
3146-
match self.tcx.hir().get_if_local(data.impl_def_id) {
3146+
match self.tcx.hir().get_if_local(data.impl_or_alias_def_id) {
31473147
Some(Node::Item(hir::Item {
31483148
kind: hir::ItemKind::Trait(is_auto, ..),
31493149
ident,

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
11891189
let cause = obligation.derived_cause(|derived| {
11901190
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
11911191
derived,
1192-
impl_def_id,
1192+
impl_or_alias_def_id: impl_def_id,
11931193
impl_def_predicate_index: None,
11941194
span: obligation.cause.span,
11951195
}))

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -2657,7 +2657,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
26572657
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
26582658
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
26592659
derived,
2660-
impl_def_id: def_id,
2660+
impl_or_alias_def_id: def_id,
26612661
impl_def_predicate_index: Some(index),
26622662
span,
26632663
}))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// Regression test for #108132: do not ICE upon unmet trait alias constraint in generic impl
2+
3+
#![feature(trait_alias)]
4+
5+
trait IteratorAlias = Iterator;
6+
7+
struct Foo<I>(I);
8+
9+
impl<I: IteratorAlias> Foo<I> {
10+
fn f() {}
11+
}
12+
13+
fn main() {
14+
Foo::<()>::f() //~ trait bounds were not satisfied
15+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
error[E0599]: the function or associated item `f` exists for struct `Foo<()>`, but its trait bounds were not satisfied
2+
--> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:14:16
3+
|
4+
LL | struct Foo<I>(I);
5+
| ------------- function or associated item `f` not found for this struct
6+
...
7+
LL | Foo::<()>::f()
8+
| ^ function or associated item cannot be called on `Foo<()>` due to unsatisfied trait bounds
9+
|
10+
note: trait bound `(): Iterator` was not satisfied
11+
--> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:5:23
12+
|
13+
LL | trait IteratorAlias = Iterator;
14+
| ------------- ^^^^^^^^ unsatisfied trait bound introduced here
15+
note: trait bound `(): IteratorAlias` was not satisfied
16+
--> $DIR/issue-108132-unmet-trait-alias-bound-on-generic-impl.rs:9:9
17+
|
18+
LL | impl<I: IteratorAlias> Foo<I> {
19+
| ^^^^^^^^^^^^^ ------
20+
| |
21+
| unsatisfied trait bound introduced here
22+
23+
error: aborting due to previous error
24+
25+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)