Constify trait aliases
This commit is contained in:
@@ -3626,6 +3626,7 @@ impl Default for FnHeader {
|
|||||||
|
|
||||||
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
#[derive(Clone, Encodable, Decodable, Debug, Walkable)]
|
||||||
pub struct TraitAlias {
|
pub struct TraitAlias {
|
||||||
|
pub constness: Const,
|
||||||
pub ident: Ident,
|
pub ident: Ident,
|
||||||
pub generics: Generics,
|
pub generics: Generics,
|
||||||
#[visitable(extra = BoundKind::Bound)]
|
#[visitable(extra = BoundKind::Bound)]
|
||||||
|
|||||||
@@ -833,8 +833,8 @@ macro_rules! common_visitor_and_walkers {
|
|||||||
visit_visitable!($($mut)? vis, impl_),
|
visit_visitable!($($mut)? vis, impl_),
|
||||||
ItemKind::Trait(trait_) =>
|
ItemKind::Trait(trait_) =>
|
||||||
visit_visitable!($($mut)? vis, trait_),
|
visit_visitable!($($mut)? vis, trait_),
|
||||||
ItemKind::TraitAlias(box TraitAlias { ident, generics, bounds }) => {
|
ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds}) => {
|
||||||
visit_visitable!($($mut)? vis, ident, generics);
|
visit_visitable!($($mut)? vis, constness, ident, generics);
|
||||||
visit_visitable_with!($($mut)? vis, bounds, BoundKind::Bound)
|
visit_visitable_with!($($mut)? vis, bounds, BoundKind::Bound)
|
||||||
}
|
}
|
||||||
ItemKind::MacCall(m) =>
|
ItemKind::MacCall(m) =>
|
||||||
|
|||||||
@@ -415,7 +415,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
);
|
);
|
||||||
hir::ItemKind::Trait(constness, *is_auto, safety, ident, generics, bounds, items)
|
hir::ItemKind::Trait(constness, *is_auto, safety, ident, generics, bounds, items)
|
||||||
}
|
}
|
||||||
ItemKind::TraitAlias(box 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 ident = self.lower_ident(*ident);
|
||||||
let (generics, bounds) = self.lower_generics(
|
let (generics, bounds) = self.lower_generics(
|
||||||
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 }) => {
|
ItemKind::MacroDef(ident, MacroDef { body, macro_rules }) => {
|
||||||
let ident = self.lower_ident(*ident);
|
let ident = self.lower_ident(*ident);
|
||||||
|
|||||||
@@ -385,8 +385,11 @@ impl<'a> State<'a> {
|
|||||||
let empty = item.attrs.is_empty() && items.is_empty();
|
let empty = item.attrs.is_empty() && items.is_empty();
|
||||||
self.bclose(item.span, empty, cb);
|
self.bclose(item.span, empty, cb);
|
||||||
}
|
}
|
||||||
ast::ItemKind::TraitAlias(box TraitAlias { ident, generics, bounds }) => {
|
ast::ItemKind::TraitAlias(box TraitAlias { constness, ident, generics, bounds }) => {
|
||||||
let (cb, ib) = self.head(visibility_qualified(&item.vis, "trait"));
|
let (cb, ib) = self.head("");
|
||||||
|
self.print_visibility(&item.vis);
|
||||||
|
self.print_constness(*constness);
|
||||||
|
self.word_nbsp("trait");
|
||||||
self.print_ident(*ident);
|
self.print_ident(*ident);
|
||||||
self.print_generic_params(&generics.params);
|
self.print_generic_params(&generics.params);
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
|
|||||||
@@ -4245,8 +4245,8 @@ impl<'hir> Item<'hir> {
|
|||||||
ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
|
ItemKind::Trait(constness, is_auto, safety, ident, generics, bounds, items),
|
||||||
(*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>),
|
expect_trait_alias, (Constness, Ident, &'hir Generics<'hir>, GenericBounds<'hir>),
|
||||||
ItemKind::TraitAlias(ident, generics, bounds), (*ident, generics, bounds);
|
ItemKind::TraitAlias(constness, ident, generics, bounds), (*constness, *ident, generics, bounds);
|
||||||
|
|
||||||
expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
|
expect_impl, &Impl<'hir>, ItemKind::Impl(imp), imp;
|
||||||
}
|
}
|
||||||
@@ -4423,7 +4423,7 @@ pub enum ItemKind<'hir> {
|
|||||||
&'hir [TraitItemId],
|
&'hir [TraitItemId],
|
||||||
),
|
),
|
||||||
/// A trait alias.
|
/// 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 { .. }`.
|
/// An implementation, e.g., `impl<A> Trait for Foo { .. }`.
|
||||||
Impl(Impl<'hir>),
|
Impl(Impl<'hir>),
|
||||||
@@ -4468,7 +4468,7 @@ impl ItemKind<'_> {
|
|||||||
| ItemKind::Struct(ident, ..)
|
| ItemKind::Struct(ident, ..)
|
||||||
| ItemKind::Union(ident, ..)
|
| ItemKind::Union(ident, ..)
|
||||||
| ItemKind::Trait(_, _, _, ident, ..)
|
| ItemKind::Trait(_, _, _, ident, ..)
|
||||||
| ItemKind::TraitAlias(ident, ..) => Some(ident),
|
| ItemKind::TraitAlias(_, ident, ..) => Some(ident),
|
||||||
|
|
||||||
ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
|
ItemKind::Use(_, UseKind::Glob | UseKind::ListStem)
|
||||||
| ItemKind::ForeignMod { .. }
|
| ItemKind::ForeignMod { .. }
|
||||||
@@ -4486,7 +4486,7 @@ impl ItemKind<'_> {
|
|||||||
| ItemKind::Struct(_, generics, _)
|
| ItemKind::Struct(_, generics, _)
|
||||||
| ItemKind::Union(_, generics, _)
|
| ItemKind::Union(_, generics, _)
|
||||||
| ItemKind::Trait(_, _, _, _, generics, _, _)
|
| ItemKind::Trait(_, _, _, _, generics, _, _)
|
||||||
| ItemKind::TraitAlias(_, generics, _)
|
| ItemKind::TraitAlias(_, _, generics, _)
|
||||||
| ItemKind::Impl(Impl { generics, .. }) => generics,
|
| ItemKind::Impl(Impl { generics, .. }) => generics,
|
||||||
_ => return None,
|
_ => return None,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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_param_bound, bounds);
|
||||||
walk_list!(visitor, visit_trait_item_ref, trait_item_refs);
|
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_ident(ident));
|
||||||
try_visit!(visitor.visit_generics(generics));
|
try_visit!(visitor.visit_generics(generics));
|
||||||
walk_list!(visitor, visit_param_bound, bounds);
|
walk_list!(visitor, visit_param_bound, bounds);
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
ItemKind::Trait(_, _, _, _, _, self_bounds, ..)
|
ItemKind::Trait(_, _, _, _, _, self_bounds, ..)
|
||||||
| ItemKind::TraitAlias(_, _, self_bounds) => {
|
| ItemKind::TraitAlias(_, _, _, self_bounds) => {
|
||||||
is_trait = Some((self_bounds, item.span));
|
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 {
|
let (generics, superbounds) = match item.kind {
|
||||||
hir::ItemKind::Trait(.., generics, supertraits, _) => (generics, supertraits),
|
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"),
|
_ => span_bug!(item.span, "super_predicates invoked on non-trait"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -632,7 +632,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
|||||||
| hir::ItemKind::Struct(_, generics, _)
|
| hir::ItemKind::Struct(_, generics, _)
|
||||||
| hir::ItemKind::Union(_, generics, _)
|
| hir::ItemKind::Union(_, generics, _)
|
||||||
| hir::ItemKind::Trait(_, _, _, _, generics, ..)
|
| hir::ItemKind::Trait(_, _, _, _, generics, ..)
|
||||||
| hir::ItemKind::TraitAlias(_, generics, ..)
|
| hir::ItemKind::TraitAlias(_, _, generics, ..)
|
||||||
| hir::ItemKind::Impl(hir::Impl { generics, .. }) => {
|
| hir::ItemKind::Impl(hir::Impl { generics, .. }) => {
|
||||||
// These kinds of items have only early-bound lifetime parameters.
|
// These kinds of items have only early-bound lifetime parameters.
|
||||||
self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item));
|
self.visit_early(item.hir_id(), generics, |this| intravisit::walk_item(this, item));
|
||||||
|
|||||||
@@ -765,8 +765,10 @@ impl<'a> State<'a> {
|
|||||||
}
|
}
|
||||||
self.bclose(item.span, cb);
|
self.bclose(item.span, cb);
|
||||||
}
|
}
|
||||||
hir::ItemKind::TraitAlias(ident, generics, bounds) => {
|
hir::ItemKind::TraitAlias(constness, ident, generics, bounds) => {
|
||||||
let (cb, ib) = self.head("trait");
|
let (cb, ib) = self.head("");
|
||||||
|
self.print_constness(constness);
|
||||||
|
self.word_nbsp("trait");
|
||||||
self.print_ident(ident);
|
self.print_ident(ident);
|
||||||
self.print_generic_params(generics.params);
|
self.print_generic_params(generics.params);
|
||||||
self.nbsp();
|
self.nbsp();
|
||||||
|
|||||||
@@ -1594,7 +1594,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Node::Item(hir::Item {
|
Node::Item(hir::Item {
|
||||||
kind:
|
kind:
|
||||||
hir::ItemKind::Trait(_, _, _, ident, ..)
|
hir::ItemKind::Trait(_, _, _, ident, ..)
|
||||||
| hir::ItemKind::TraitAlias(ident, ..),
|
| hir::ItemKind::TraitAlias(_, ident, ..),
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
// We may also encounter unsatisfied GAT or method bounds
|
// We may also encounter unsatisfied GAT or method bounds
|
||||||
|
|||||||
@@ -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_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_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_alias_cannot_be_unsafe = trait aliases cannot be `unsafe`
|
||||||
|
|
||||||
parse_trait_impl_modifier_in_inherent_impl = inherent impls cannot be {$modifier_name}
|
parse_trait_impl_modifier_in_inherent_impl = inherent impls cannot be {$modifier_name}
|
||||||
|
|||||||
@@ -1999,14 +1999,6 @@ pub(crate) struct TraitAliasCannotBeAuto {
|
|||||||
pub span: Span,
|
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)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parse_trait_alias_cannot_be_unsafe)]
|
#[diag(parse_trait_alias_cannot_be_unsafe)]
|
||||||
pub(crate) struct TraitAliasCannotBeUnsafe {
|
pub(crate) struct TraitAliasCannotBeUnsafe {
|
||||||
|
|||||||
@@ -943,9 +943,6 @@ impl<'a> Parser<'a> {
|
|||||||
self.expect_semi()?;
|
self.expect_semi()?;
|
||||||
|
|
||||||
let whole_span = lo.to(self.prev_token.span);
|
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 {
|
if is_auto == IsAuto::Yes {
|
||||||
self.dcx().emit_err(errors::TraitAliasCannotBeAuto { span: whole_span });
|
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);
|
self.psess.gated_spans.gate(sym::trait_alias, whole_span);
|
||||||
|
|
||||||
Ok(ItemKind::TraitAlias(Box::new(TraitAlias { ident, generics, bounds })))
|
Ok(ItemKind::TraitAlias(Box::new(TraitAlias { constness, ident, generics, bounds })))
|
||||||
} else {
|
} else {
|
||||||
// It's a normal trait.
|
// It's a normal trait.
|
||||||
generics.where_clause = self.parse_where_clause()?;
|
generics.where_clause = self.parse_where_clause()?;
|
||||||
|
|||||||
@@ -476,9 +476,8 @@ pub fn report_dyn_incompatibility<'tcx>(
|
|||||||
let trait_str = tcx.def_path_str(trait_def_id);
|
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 {
|
let trait_span = tcx.hir_get_if_local(trait_def_id).and_then(|node| match node {
|
||||||
hir::Node::Item(item) => match item.kind {
|
hir::Node::Item(item) => match item.kind {
|
||||||
hir::ItemKind::Trait(_, _, _, ident, ..) | hir::ItemKind::TraitAlias(ident, _, _) => {
|
hir::ItemKind::Trait(_, _, _, ident, ..)
|
||||||
Some(ident.span)
|
| hir::ItemKind::TraitAlias(_, ident, _, _) => Some(ident.span),
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
},
|
},
|
||||||
_ => None,
|
_ => None,
|
||||||
|
|||||||
@@ -364,7 +364,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
| hir::ItemKind::Fn { generics, .. }
|
| hir::ItemKind::Fn { generics, .. }
|
||||||
| hir::ItemKind::TyAlias(_, generics, _)
|
| hir::ItemKind::TyAlias(_, generics, _)
|
||||||
| hir::ItemKind::Const(_, generics, _, _)
|
| hir::ItemKind::Const(_, generics, _, _)
|
||||||
| hir::ItemKind::TraitAlias(_, generics, _),
|
| hir::ItemKind::TraitAlias(_, _, generics, _),
|
||||||
..
|
..
|
||||||
})
|
})
|
||||||
| hir::Node::TraitItem(hir::TraitItem { generics, .. })
|
| hir::Node::TraitItem(hir::TraitItem { generics, .. })
|
||||||
@@ -444,7 +444,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
|
|||||||
| hir::ItemKind::Fn { generics, .. }
|
| hir::ItemKind::Fn { generics, .. }
|
||||||
| hir::ItemKind::TyAlias(_, generics, _)
|
| hir::ItemKind::TyAlias(_, generics, _)
|
||||||
| hir::ItemKind::Const(_, generics, _, _)
|
| hir::ItemKind::Const(_, generics, _, _)
|
||||||
| hir::ItemKind::TraitAlias(_, generics, _),
|
| hir::ItemKind::TraitAlias(_, _, generics, _),
|
||||||
..
|
..
|
||||||
}) if finder.can_suggest_bound(generics) => {
|
}) if finder.can_suggest_bound(generics) => {
|
||||||
// Missing generic type parameter bound.
|
// Missing generic type parameter bound.
|
||||||
|
|||||||
@@ -2828,7 +2828,7 @@ fn clean_maybe_renamed_item<'tcx>(
|
|||||||
variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(),
|
variants: def.variants.iter().map(|v| clean_variant(v, cx)).collect(),
|
||||||
generics: clean_generics(generics, cx),
|
generics: clean_generics(generics, cx),
|
||||||
}),
|
}),
|
||||||
ItemKind::TraitAlias(_, generics, bounds) => TraitAliasItem(TraitAlias {
|
ItemKind::TraitAlias(_, _, generics, bounds) => TraitAliasItem(TraitAlias {
|
||||||
generics: clean_generics(generics, cx),
|
generics: clean_generics(generics, cx),
|
||||||
bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
|
bounds: bounds.iter().filter_map(|x| clean_generic_bound(x, cx)).collect(),
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -528,7 +528,7 @@ impl LateLintPass<'_> for ItemNameRepetitions {
|
|||||||
| ItemKind::Macro(ident, ..)
|
| ItemKind::Macro(ident, ..)
|
||||||
| ItemKind::Static(_, ident, ..)
|
| ItemKind::Static(_, ident, ..)
|
||||||
| ItemKind::Trait(_, _, _, ident, ..)
|
| ItemKind::Trait(_, _, _, ident, ..)
|
||||||
| ItemKind::TraitAlias(ident, ..)
|
| ItemKind::TraitAlias(_, ident, ..)
|
||||||
| ItemKind::TyAlias(ident, ..)
|
| ItemKind::TyAlias(ident, ..)
|
||||||
| ItemKind::Union(ident, ..)
|
| ItemKind::Union(ident, ..)
|
||||||
| ItemKind::Use(_, UseKind::Single(ident)) => ident,
|
| ItemKind::Use(_, UseKind::Single(ident)) => ident,
|
||||||
|
|||||||
@@ -478,13 +478,20 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
|
|||||||
ident: li,
|
ident: li,
|
||||||
generics: lg,
|
generics: lg,
|
||||||
bounds: lb,
|
bounds: lb,
|
||||||
|
constness: lc,
|
||||||
}),
|
}),
|
||||||
TraitAlias(box ast::TraitAlias {
|
TraitAlias(box ast::TraitAlias {
|
||||||
ident: ri,
|
ident: ri,
|
||||||
generics: rg,
|
generics: rg,
|
||||||
bounds: rb,
|
bounds: rb,
|
||||||
|
constness: rc,
|
||||||
}),
|
}),
|
||||||
) => eq_id(*li, *ri) && eq_generics(lg, rg) && over(lb, rb, eq_generic_bound),
|
) => {
|
||||||
|
matches!(lc, ast::Const::No) == matches!(rc, ast::Const::No)
|
||||||
|
&& eq_id(*li, *ri)
|
||||||
|
&& eq_generics(lg, rg)
|
||||||
|
&& over(lb, rb, eq_generic_bound)
|
||||||
|
},
|
||||||
(
|
(
|
||||||
Impl(ast::Impl {
|
Impl(ast::Impl {
|
||||||
generics: lg,
|
generics: lg,
|
||||||
|
|||||||
46
tests/ui/consts/trait_alias.fail.stderr
Normal file
46
tests/ui/consts/trait_alias.fail.stderr
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
error: `[const]` is not allowed here
|
||||||
|
--> $DIR/trait_alias.rs:14:19
|
||||||
|
|
|
||||||
|
LL | const trait Foo = [const] Bar + Baz;
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this item cannot have `[const]` trait bounds
|
||||||
|
|
||||||
|
error: `[const]` can only be applied to `const` traits
|
||||||
|
--> $DIR/trait_alias.rs:17:17
|
||||||
|
|
|
||||||
|
LL | const fn foo<T: [const] Foo>(x: &T) {
|
||||||
|
| ^^^^^^^ can't be applied to `Foo`
|
||||||
|
|
|
||||||
|
help: mark `Foo` as `const` to allow it to have `const` implementations
|
||||||
|
|
|
||||||
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
|
||||||
|
| ++++++++++++++
|
||||||
|
|
||||||
|
error: `[const]` can only be applied to `const` traits
|
||||||
|
--> $DIR/trait_alias.rs:17:17
|
||||||
|
|
|
||||||
|
LL | const fn foo<T: [const] Foo>(x: &T) {
|
||||||
|
| ^^^^^^^ can't be applied to `Foo`
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
help: mark `Foo` as `const` to allow it to have `const` implementations
|
||||||
|
|
|
||||||
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
|
||||||
|
| ++++++++++++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: [const] Bar` is not satisfied
|
||||||
|
--> $DIR/trait_alias.rs:20:7
|
||||||
|
|
|
||||||
|
LL | x.bar();
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: [const] Baz` is not satisfied
|
||||||
|
--> $DIR/trait_alias.rs:24:11
|
||||||
|
|
|
||||||
|
LL | x.baz();
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: aborting due to 5 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
40
tests/ui/consts/trait_alias.pass.stderr
Normal file
40
tests/ui/consts/trait_alias.pass.stderr
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
error: `[const]` is not allowed here
|
||||||
|
--> $DIR/trait_alias.rs:14:19
|
||||||
|
|
|
||||||
|
LL | const trait Foo = [const] Bar + Baz;
|
||||||
|
| ^^^^^^^
|
||||||
|
|
|
||||||
|
= note: this item cannot have `[const]` trait bounds
|
||||||
|
|
||||||
|
error: `[const]` can only be applied to `const` traits
|
||||||
|
--> $DIR/trait_alias.rs:17:17
|
||||||
|
|
|
||||||
|
LL | const fn foo<T: [const] Foo>(x: &T) {
|
||||||
|
| ^^^^^^^ can't be applied to `Foo`
|
||||||
|
|
|
||||||
|
help: mark `Foo` as `const` to allow it to have `const` implementations
|
||||||
|
|
|
||||||
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
|
||||||
|
| ++++++++++++++
|
||||||
|
|
||||||
|
error: `[const]` can only be applied to `const` traits
|
||||||
|
--> $DIR/trait_alias.rs:17:17
|
||||||
|
|
|
||||||
|
LL | const fn foo<T: [const] Foo>(x: &T) {
|
||||||
|
| ^^^^^^^ can't be applied to `Foo`
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
help: mark `Foo` as `const` to allow it to have `const` implementations
|
||||||
|
|
|
||||||
|
LL | #[const_trait] const trait Foo = [const] Bar + Baz;
|
||||||
|
| ++++++++++++++
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `T: [const] Bar` is not satisfied
|
||||||
|
--> $DIR/trait_alias.rs:20:7
|
||||||
|
|
|
||||||
|
LL | x.bar();
|
||||||
|
| ^^^
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
||||||
31
tests/ui/consts/trait_alias.rs
Normal file
31
tests/ui/consts/trait_alias.rs
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#![feature(trait_alias, const_trait_impl)]
|
||||||
|
//@ revisions: pass fail
|
||||||
|
|
||||||
|
const trait Bar {
|
||||||
|
fn bar(&self) {}
|
||||||
|
}
|
||||||
|
const trait Baz {
|
||||||
|
fn baz(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl const Bar for () {}
|
||||||
|
impl const Baz for () {}
|
||||||
|
|
||||||
|
const trait Foo = [const] Bar + Baz;
|
||||||
|
//~^ ERROR: `[const]` is not allowed here
|
||||||
|
|
||||||
|
const fn foo<T: [const] Foo>(x: &T) {
|
||||||
|
//~^ ERROR: `[const]` can only be applied to `const` traits
|
||||||
|
//~| ERROR: `[const]` can only be applied to `const` traits
|
||||||
|
x.bar();
|
||||||
|
//~^ ERROR: the trait bound `T: [const] Bar` is not satisfied
|
||||||
|
#[cfg(fail)]
|
||||||
|
{
|
||||||
|
x.baz();
|
||||||
|
//[fail]~^ ERROR: the trait bound `T: [const] Baz` is not satisfied
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = foo(&());
|
||||||
|
|
||||||
|
fn main() {}
|
||||||
Reference in New Issue
Block a user