diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index fc9678233c3b0..972d1376a1b26 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -20,9 +20,9 @@ use super::util; use super::util::{closure_trait_ref_and_return_type, predicate_for_trait_def}; use super::wf; use super::{ - ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, Normalized, Obligation, - ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, Selection, SelectionError, - SelectionResult, TraitObligation, TraitQueryMode, + DerivedObligation, ErrorReporting, ImplDerivedObligation, ImplDerivedObligationCause, + Normalized, Obligation, ObligationCause, ObligationCauseCode, Overflow, PredicateObligation, + Selection, SelectionError, SelectionResult, TraitObligation, TraitQueryMode, }; use crate::infer::{InferCtxt, InferOk, TypeFreshener}; @@ -2657,14 +2657,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { let predicates = predicates.instantiate_own(tcx, substs); let mut obligations = Vec::with_capacity(predicates.len()); for (index, (predicate, span)) in predicates.into_iter().enumerate() { - let cause = cause.clone().derived_cause(parent_trait_pred, |derived| { - ImplDerivedObligation(Box::new(ImplDerivedObligationCause { - derived, - impl_def_id: def_id, - impl_def_predicate_index: Some(index), - span, - })) - }); + let cause = if tcx.is_trait_alias(def_id) { + cause.clone().derived_cause(parent_trait_pred, DerivedObligation) + } else { + cause.clone().derived_cause(parent_trait_pred, |derived| { + ImplDerivedObligation(Box::new(ImplDerivedObligationCause { + derived, + impl_def_id: def_id, + impl_def_predicate_index: Some(index), + span, + })) + }) + }; let predicate = normalize_with_depth_to( self, param_env, diff --git a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs new file mode 100644 index 0000000000000..d254c0ae3ef92 --- /dev/null +++ b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.rs @@ -0,0 +1,11 @@ +// Regression test for #108072: do not ICE upon unmet trait alias constraint + +#![feature(trait_alias)] + +trait IteratorAlias = Iterator; + +fn f(_: impl IteratorAlias) {} + +fn main() { + f(()) //~ `()` is not an iterator +} diff --git a/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr new file mode 100644 index 0000000000000..b2f401e916e13 --- /dev/null +++ b/tests/ui/traits/alias/issue-108072-unmet-trait-alias-bound.stderr @@ -0,0 +1,18 @@ +error[E0277]: `()` is not an iterator + --> $DIR/issue-108072-unmet-trait-alias-bound.rs:10:7 + | +LL | f(()) + | - ^^ `()` is not an iterator + | | + | required by a bound introduced by this call + | + = help: the trait `Iterator` is not implemented for `()` +note: required by a bound in `f` + --> $DIR/issue-108072-unmet-trait-alias-bound.rs:7:14 + | +LL | fn f(_: impl IteratorAlias) {} + | ^^^^^^^^^^^^^ required by this bound in `f` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`.