Auto merge of #148314 - matthiaskrgr:rollup-yo55adr, r=matthiaskrgr
Some checks failed
Post merge analysis / analysis (push) Has been cancelled
GHCR image mirroring / DockerHub mirror (push) Has been cancelled
Bump dependencies in Cargo.lock / skip if S-waiting-on-bors (push) Has been cancelled
Bump dependencies in Cargo.lock / update dependencies (push) Has been cancelled
Bump dependencies in Cargo.lock / amend PR (push) Has been cancelled

Rollup of 4 pull requests

Successful merges:

 - rust-lang/rust#144291 (Constify trait aliases)
 - rust-lang/rust#147633 (Add new `--bypass-ignore-backends` option)
 - rust-lang/rust#148252 (Improve diagnose for unconditional panic when resource limit)
 - rust-lang/rust#148262 (Fix types being marked as dead when they are inferred generic arguments)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors
2025-10-31 01:57:02 +00:00
54 changed files with 346 additions and 107 deletions

View File

@@ -3540,8 +3540,9 @@ impl Item {
ItemKind::Const(i) => Some(&i.generics),
ItemKind::Fn(i) => Some(&i.generics),
ItemKind::TyAlias(i) => Some(&i.generics),
ItemKind::TraitAlias(_, generics, _)
| ItemKind::Enum(_, generics, _)
ItemKind::TraitAlias(i) => Some(&i.generics),
ItemKind::Enum(_, generics, _)
| ItemKind::Struct(_, generics, _)
| ItemKind::Union(_, generics, _) => Some(&generics),
ItemKind::Trait(i) => Some(&i.generics),
@@ -3623,6 +3624,15 @@ impl Default for FnHeader {
}
}
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct TraitAlias {
pub constness: Const,
pub ident: Ident,
pub generics: Generics,
#[visitable(extra = BoundKind::Bound)]
pub bounds: GenericBounds,
}
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
pub struct Trait {
pub constness: Const,
@@ -3798,7 +3808,7 @@ pub enum ItemKind {
/// Trait alias.
///
/// E.g., `trait Foo = Bar + Quux;`.
TraitAlias(Ident, Generics, GenericBounds),
TraitAlias(Box<TraitAlias>),
/// An implementation.
///
/// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`.
@@ -3831,7 +3841,7 @@ impl ItemKind {
| ItemKind::Struct(ident, ..)
| ItemKind::Union(ident, ..)
| ItemKind::Trait(box Trait { ident, .. })
| ItemKind::TraitAlias(ident, ..)
| ItemKind::TraitAlias(box TraitAlias { ident, .. })
| ItemKind::MacroDef(ident, _)
| ItemKind::Delegation(box Delegation { ident, .. }) => Some(ident),
@@ -3888,7 +3898,7 @@ impl ItemKind {
| Self::Struct(_, generics, _)
| Self::Union(_, generics, _)
| Self::Trait(box Trait { generics, .. })
| Self::TraitAlias(_, generics, _)
| Self::TraitAlias(box TraitAlias { generics, .. })
| Self::Impl(Impl { generics, .. }) => Some(generics),
_ => None,
}
@@ -4050,8 +4060,8 @@ mod size_asserts {
static_assert_size!(GenericBound, 88);
static_assert_size!(Generics, 40);
static_assert_size!(Impl, 64);
static_assert_size!(Item, 144);
static_assert_size!(ItemKind, 80);
static_assert_size!(Item, 136);
static_assert_size!(ItemKind, 72);
static_assert_size!(LitKind, 24);
static_assert_size!(Local, 96);
static_assert_size!(MetaItemLit, 40);

View File

@@ -833,8 +833,8 @@ macro_rules! common_visitor_and_walkers {
visit_visitable!($($mut)? vis, impl_),
ItemKind::Trait(trait_) =>
visit_visitable!($($mut)? vis, trait_),
ItemKind::TraitAlias(ident, generics, bounds) => {
visit_visitable!($($mut)? vis, ident, generics);
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => {
visit_visitable!($($mut)? vis, constness, ident, generics);
visit_visitable_with!($($mut)? vis, bounds, BoundKind::Bound)
}
ItemKind::MacCall(m) =>

View File

@@ -415,7 +415,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
);
hir::ItemKind::Trait(constness, *is_auto, safety, ident, generics, bounds, items)
}
ItemKind::TraitAlias(ident, generics, bounds) => {
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => {
let constness = self.lower_constness(*constness);
let ident = self.lower_ident(*ident);
let (generics, bounds) = self.lower_generics(
generics,
@@ -429,7 +430,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
)
},
);
hir::ItemKind::TraitAlias(ident, generics, bounds)
hir::ItemKind::TraitAlias(constness, ident, generics, bounds)
}
ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
let ident = self.lower_ident(*ident);

View File

@@ -1192,6 +1192,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
walk_list!(this, visit_assoc_item, items, AssocCtxt::Trait);
});
}
ItemKind::TraitAlias(box TraitAlias { constness, generics, bounds, .. }) => {
let disallowed = matches!(constness, ast::Const::No)
.then(|| TildeConstReason::Trait { span: item.span });
self.with_tilde_const(disallowed, |this| {
this.visit_generics(generics);
walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits)
});
}
ItemKind::Mod(safety, ident, mod_kind) => {
if let &Safety::Unsafe(span) = safety {
self.dcx().emit_err(errors::UnsafeItem { span, kind: "module" });

View File

@@ -1,7 +1,6 @@
use ast::StaticItem;
use itertools::{Itertools, Position};
use rustc_ast as ast;
use rustc_ast::ModKind;
use rustc_ast::{self as ast, ModKind, TraitAlias};
use rustc_span::Ident;
use crate::pp::BoxMarker;
@@ -386,8 +385,11 @@ impl<'a> State<'a> {
let empty = item.attrs.is_empty() && items.is_empty();
self.bclose(item.span, empty, cb);
}
ast::ItemKind::TraitAlias(ident, generics, bounds) => {
let (cb, ib) = self.head(visibility_qualified(&item.vis, "trait"));
ast::ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => {
let (cb, ib) = self.head("");
self.print_visibility(&item.vis);
self.print_constness(*constness);
self.word_nbsp("trait");
self.print_ident(*ident);
self.print_generic_params(&generics.params);
self.nbsp();

View File

@@ -4151,8 +4151,8 @@ impl<'hir> Item<'hir> {
ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
(*constness, *is_auto, *safety, *ident, generics, bounds, items);
expect_trait_alias, (Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
expect_trait_alias, (Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds);
expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
}
@@ -4329,7 +4329,7 @@ pub enum ItemKind<'hir> {
&'hir [TraitItemId],
),
/// A trait alias.
TraitAlias(Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
TraitAlias(Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
Impl(Impl<'hir>),
@@ -4374,7 +4374,7 @@ impl ItemKind<'_> {
| ItemKind::Struct(ident, ..)
| ItemKind::Union(ident, ..)
| ItemKind::Trait(_, _, _, ident, ..)
| ItemKind::TraitAlias(ident, ..) => Some(ident),
| ItemKind::TraitAlias(_, ident, ..) => Some(ident),
ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
| ItemKind::ForeignMod { .. }
@@ -4392,7 +4392,7 @@ impl ItemKind<'_> {
| ItemKind::Struct(_, generics, _)
| ItemKind::Union(_, generics, _)
| ItemKind::Trait(_, _, _, _, generics, _, _)
| ItemKind::TraitAlias(_, generics, _)
| ItemKind::TraitAlias(_, _, generics, _)
| ItemKind::Impl(Impl { generics, .. }) => generics,
_ => return None,
})

View File

@@ -626,7 +626,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) -> V::
walk_list!(visitor, visit_param_bound, bounds);
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
}
ItemKind::TraitAlias(ident, ref generics, bounds) => {
ItemKind::TraitAlias(_constness, ident, ref generics, bounds) => {
try_visit!(visitor.visit_ident(ident));
try_visit!(visitor.visit_generics(generics));
walk_list!(visitor, visit_param_bound, bounds);

View File

@@ -847,7 +847,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::TraitDef {
hir::ItemKind::Trait(constness, is_auto, safety, ..) => {
(constness, false, is_auto == hir::IsAuto::Yes, safety)
}
hir::ItemKind::TraitAlias(..) => (hir::Constness::NotConst, true, false, hir::Safety::Safe),
hir::ItemKind::TraitAlias(constness, ..) => (constness, true, false, hir::Safety::Safe),
_ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
};

View File

@@ -167,7 +167,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
}
}
ItemKind::Trait(_, _, _, _, _, self_bounds, ..)
| ItemKind::TraitAlias(_, _, self_bounds) => {
| ItemKind::TraitAlias(_, _, _, self_bounds) => {
is_trait = Some((self_bounds, item.span));
}
_ => {}
@@ -654,7 +654,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
let (generics, superbounds) = match item.kind {
hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
hir::ItemKind::TraitAlias(_, _, generics, supertraits) => (generics, supertraits),
_ => span_bug!(item.span, "super_predicates invoked on non-trait"),
};
@@ -1032,7 +1032,10 @@ pub(super) fn const_conditions<'tcx>(
hir::ItemKind::Impl(impl_) => (impl_.generics, None, false),
hir::ItemKind::Fn { generics, .. } => (generics, None, false),
hir::ItemKind::Trait(_, _, _, _, generics, supertraits, _) => {
(generics, Some((item.owner_id.def_id, supertraits)), false)
(generics, Some((Some(item.owner_id.def_id), supertraits)), false)
}
hir::ItemKind::TraitAlias(_, _, generics, supertraits) => {
(generics, Some((None, supertraits)), false)
}
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
},
@@ -1089,12 +1092,14 @@ pub(super) fn const_conditions<'tcx>(
}
if let Some((def_id, supertraits)) = trait_def_id_and_supertraits {
// We've checked above that the trait is conditionally const.
bounds.push((
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id()))
.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
DUMMY_SP,
));
if let Some(def_id) = def_id {
// We've checked above that the trait is conditionally const.
bounds.push((
ty::Binder::dummy(ty::TraitRef::identity(tcx, def_id.to_def_id()))
.to_host_effect_clause(tcx, ty::BoundConstness::Maybe),
DUMMY_SP,
));
}
icx.lowerer().lower_bounds(
tcx.types.self_param,
@@ -1143,13 +1148,14 @@ pub(super) fn explicit_implied_const_bounds<'tcx>(
span_bug!(tcx.def_span(def_id), "RPITIT in impl should not have item bounds")
}
None => match tcx.hir_node_by_def_id(def_id) {
Node::Item(hir::Item { kind: hir::ItemKind::Trait(..), .. }) => {
implied_predicates_with_filter(
tcx,
def_id.to_def_id(),
PredicateFilter::SelfConstIfConst,
)
}
Node::Item(hir::Item {
kind: hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..),
..
}) => implied_predicates_with_filter(
tcx,
def_id.to_def_id(),
PredicateFilter::SelfConstIfConst,
),
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
| Node::OpaqueTy(_) => {
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)

View File

@@ -632,7 +632,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
| hir::ItemKind::Struct(_, generics, _)
| hir::ItemKind::Union(_, generics, _)
| hir::ItemKind::Trait(_, _, _, _, generics, ..)
| hir::ItemKind::TraitAlias(_, generics, ..)
| hir::ItemKind::TraitAlias(_, _, generics, ..)
| hir::ItemKind::Impl(hir::Impl { generics, .. }) => {
// These kinds of items have only early-bound lifetime parameters.
self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item));

View File

@@ -765,8 +765,10 @@ impl<'a> State<'a> {
}
self.bclose(item.span, cb);
}
hir::ItemKind::TraitAlias(ident, generics, bounds) => {
let (cb, ib) = self.head("trait");
hir::ItemKind::TraitAlias(constness, ident, generics, bounds) => {
let (cb, ib) = self.head("");
self.print_constness(constness);
self.word_nbsp("trait");
self.print_ident(ident);
self.print_generic_params(generics.params);
self.nbsp();

View File

@@ -1596,7 +1596,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
Node::Item(hir::Item {
kind:
hir::ItemKind::Trait(_, _, _, ident, ..)
| hir::ItemKind::TraitAlias(ident, ..),
| hir::ItemKind::TraitAlias(_, ident, ..),
..
})
// We may also encounter unsatisfied GAT or method bounds

View File

@@ -288,7 +288,15 @@ pub(crate) fn run_in_thread_pool_with_globals<
pool.install(|| f(current_gcx.into_inner(), proxy))
},
)
.unwrap()
.unwrap_or_else(|err| {
let mut diag = thread_builder_diag.early_struct_fatal(format!(
"failed to spawn compiler thread pool: could not create {threads} threads ({err})",
));
diag.help(
"try lowering `-Z threads` or checking the operating system's resource limits",
);
diag.emit();
})
})
})
}

View File

@@ -160,7 +160,9 @@ impl EarlyLintPass for NonCamelCaseTypes {
ast::ItemKind::Trait(box ast::Trait { ident, .. }) => {
self.check_case(cx, "trait", ident)
}
ast::ItemKind::TraitAlias(ident, _, _) => self.check_case(cx, "trait alias", ident),
ast::ItemKind::TraitAlias(box ast::TraitAlias { ident, .. }) => {
self.check_case(cx, "trait alias", ident)
}
// N.B. This check is only for inherent associated types, so that we don't lint against
// trait impls where we should have warned for the trait definition already.

View File

@@ -2101,7 +2101,7 @@ impl<'tcx> TyCtxt<'tcx> {
DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn) => {
self.constness(def_id) == hir::Constness::Const
}
DefKind::Trait => self.is_const_trait(def_id),
DefKind::TraitAlias | DefKind::Trait => self.is_const_trait(def_id),
DefKind::AssocTy => {
let parent_def_id = self.parent(def_id);
match self.def_kind(parent_def_id) {
@@ -2144,7 +2144,6 @@ impl<'tcx> TyCtxt<'tcx> {
| DefKind::Variant
| DefKind::TyAlias
| DefKind::ForeignTy
| DefKind::TraitAlias
| DefKind::TyParam
| DefKind::Const
| DefKind::ConstParam

View File

@@ -196,10 +196,35 @@ where
}
fn consider_trait_alias_candidate(
_ecx: &mut EvalCtxt<'_, D>,
_goal: Goal<I, Self>,
ecx: &mut EvalCtxt<'_, D>,
goal: Goal<I, Self>,
) -> Result<Candidate<I>, NoSolution> {
unreachable!("trait aliases are never const")
let cx = ecx.cx();
ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
let where_clause_bounds = cx
.predicates_of(goal.predicate.def_id().into())
.iter_instantiated(cx, goal.predicate.trait_ref.args)
.map(|p| goal.with(cx, p));
let const_conditions = cx
.const_conditions(goal.predicate.def_id().into())
.iter_instantiated(cx, goal.predicate.trait_ref.args)
.map(|bound_trait_ref| {
goal.with(
cx,
bound_trait_ref.to_host_effect_clause(cx, goal.predicate.constness),
)
});
// While you could think of trait aliases to have a single builtin impl
// which uses its implied trait bounds as where-clauses, using
// `GoalSource::ImplWhereClause` here would be incorrect, as we also
// impl them, which means we're "stepping out of the impl constructor"
// again. To handle this, we treat these cycles as ambiguous for now.
ecx.add_goals(GoalSource::Misc, where_clause_bounds);
ecx.add_goals(GoalSource::Misc, const_conditions);
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
})
}
fn consider_builtin_sizedness_candidates(

View File

@@ -863,7 +863,6 @@ parse_too_short_hex_escape = numeric character escape is too short
parse_trailing_vert_not_allowed = a trailing `{$token}` is not allowed in an or-pattern
parse_trait_alias_cannot_be_auto = trait aliases cannot be `auto`
parse_trait_alias_cannot_be_const = trait aliases cannot be `const`
parse_trait_alias_cannot_be_unsafe = trait aliases cannot be `unsafe`
parse_trait_impl_modifier_in_inherent_impl = inherent impls cannot be {$modifier_name}

View File

@@ -1999,14 +1999,6 @@ pub(crate) struct TraitAliasCannotBeAuto {
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_trait_alias_cannot_be_const)]
pub(crate) struct TraitAliasCannotBeConst {
#[primary_span]
#[label(parse_trait_alias_cannot_be_const)]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(parse_trait_alias_cannot_be_unsafe)]
pub(crate) struct TraitAliasCannotBeUnsafe {

View File

@@ -943,9 +943,6 @@ impl<'a> Parser<'a> {
self.expect_semi()?;
let whole_span = lo.to(self.prev_token.span);
if let Const::Yes(_) = constness {
self.dcx().emit_err(errors::TraitAliasCannotBeConst { span: whole_span });
}
if is_auto == IsAuto::Yes {
self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
}
@@ -955,7 +952,7 @@ impl<'a> Parser<'a> {
self.psess.gated_spans.gate(sym::trait_alias, whole_span);
Ok(ItemKind::TraitAlias(ident, generics, bounds))
Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds })))
} else {
// It's a normal trait.
generics.where_clause = self.parse_where_clause()?;

View File

@@ -125,9 +125,13 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
) => {
self.check_def_id(def_id);
}
_ if self.in_pat => {}
Res::PrimTy(..) | Res::SelfCtor(..) | Res::Local(..) => {}
Res::Def(DefKind::Ctor(CtorOf::Variant, ..), ctor_def_id) => {
// Using a variant in patterns should not make the variant live,
// since we can just remove the match arm that matches the pattern
if self.in_pat {
return;
}
let variant_id = self.tcx.parent(ctor_def_id);
let enum_id = self.tcx.parent(variant_id);
self.check_def_id(enum_id);
@@ -136,6 +140,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
}
}
Res::Def(DefKind::Variant, variant_id) => {
// Using a variant in patterns should not make the variant live,
// since we can just remove the match arm that matches the pattern
if self.in_pat {
return;
}
let enum_id = self.tcx.parent(variant_id);
self.check_def_id(enum_id);
if !self.ignore_variant_stack.contains(&variant_id) {

View File

@@ -10,7 +10,7 @@ use std::sync::Arc;
use rustc_ast::visit::{self, AssocCtxt, Visitor, WalkItemKind};
use rustc_ast::{
self as ast, AssocItem, AssocItemKind, Block, ConstItem, Delegation, Fn, ForeignItem,
ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TyAlias,
ForeignItemKind, Inline, Item, ItemKind, NodeId, StaticItem, StmtKind, TraitAlias, TyAlias,
};
use rustc_attr_parsing as attr;
use rustc_attr_parsing::AttributeParser;
@@ -844,7 +844,8 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
}
// These items live in the type namespace.
ItemKind::TyAlias(box TyAlias { ident, .. }) | ItemKind::TraitAlias(ident, ..) => {
ItemKind::TyAlias(box TyAlias { ident, .. })
| ItemKind::TraitAlias(box TraitAlias { ident, .. }) => {
self.r.define_local(parent, ident, TypeNS, res, vis, sp, expansion);
}

View File

@@ -2645,7 +2645,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
);
}
ItemKind::TraitAlias(_, ref generics, ref bounds) => {
ItemKind::TraitAlias(box TraitAlias { ref generics, ref bounds, .. }) => {
// Create a new rib for the trait-wide type parameters.
self.with_generic_param_rib(
&generics.params,
@@ -5164,7 +5164,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> {
| ItemKind::Union(_, generics, _)
| ItemKind::Impl(Impl { generics, .. })
| ItemKind::Trait(box Trait { generics, .. })
| ItemKind::TraitAlias(_, generics, _) => {
| ItemKind::TraitAlias(box TraitAlias { generics, .. }) => {
if let ItemKind::Fn(box Fn { sig, .. }) = &item.kind {
self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs);
}

View File

@@ -476,9 +476,8 @@ pub fn report_dyn_incompatibility<'tcx>(
let trait_str = tcx.def_path_str(trait_def_id);
let trait_span = tcx.hir_get_if_local(trait_def_id).and_then(|node| match node {
hir::Node::Item(item) => match item.kind {
hir::ItemKind::Trait(_, _, _, ident, ..) | hir::ItemKind::TraitAlias(ident, _, _) => {
Some(ident.span)
}
hir::ItemKind::Trait(_, _, _, ident, ..)
| hir::ItemKind::TraitAlias(_, ident, _, _) => Some(ident.span),
_ => unreachable!(),
},
_ => None,

View File

@@ -364,7 +364,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
| hir::ItemKind::Fn { generics, .. }
| hir::ItemKind::TyAlias(_, generics, _)
| hir::ItemKind::Const(_, generics, _, _)
| hir::ItemKind::TraitAlias(_, generics, _),
| hir::ItemKind::TraitAlias(_, _, generics, _),
..
})
| hir::Node::TraitItem(hir::TraitItem { generics, .. })
@@ -444,7 +444,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
| hir::ItemKind::Fn { generics, .. }
| hir::ItemKind::TyAlias(_, generics, _)
| hir::ItemKind::Const(_, generics, _, _)
| hir::ItemKind::TraitAlias(_, generics, _),
| hir::ItemKind::TraitAlias(_, _, generics, _),
..
}) if finder.can_suggest_bound(generics) => {
// Missing generic type parameter bound.

View File

@@ -69,6 +69,12 @@ pub fn evaluate_host_effect_obligation<'tcx>(
Err(EvaluationFailure::NoSolution) => {}
}
match evaluate_host_effect_from_trait_alias(selcx, obligation) {
Ok(result) => return Ok(result),
Err(EvaluationFailure::Ambiguous) => return Err(EvaluationFailure::Ambiguous),
Err(EvaluationFailure::NoSolution) => {}
}
Err(EvaluationFailure::NoSolution)
}
@@ -593,3 +599,37 @@ fn evaluate_host_effect_from_selection_candidate<'tcx>(
}
})
}
fn evaluate_host_effect_from_trait_alias<'tcx>(
selcx: &mut SelectionContext<'_, 'tcx>,
obligation: &HostEffectObligation<'tcx>,
) -> Result<ThinVec<PredicateObligation<'tcx>>, EvaluationFailure> {
let tcx = selcx.tcx();
let def_id = obligation.predicate.def_id();
if !tcx.trait_is_alias(def_id) {
return Err(EvaluationFailure::NoSolution);
}
Ok(tcx
.const_conditions(def_id)
.instantiate(tcx, obligation.predicate.trait_ref.args)
.into_iter()
.map(|(trait_ref, span)| {
Obligation::new(
tcx,
obligation.cause.clone().derived_host_cause(
ty::Binder::dummy(obligation.predicate),
|derived| {
ObligationCauseCode::ImplDerivedHost(Box::new(ImplDerivedHostCause {
derived,
impl_def_id: def_id,
span,
}))
},
),
obligation.param_env,
trait_ref.to_host_effect_clause(tcx, obligation.predicate.constness),
)
})
.collect())
}