mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Rollup merge of #133218 - compiler-errors:const-opaque, r=fee1-dead
Implement `~const` item bounds in RPIT an RPIT in a `const fn` is allowed to be conditionally const itself :) r? fee1-dead or reroll
This commit is contained in:
commit
920092531f
@ -339,6 +339,8 @@ fn check_opaque_meets_bounds<'tcx>(
|
|||||||
|
|
||||||
let misc_cause = ObligationCause::misc(span, def_id);
|
let misc_cause = ObligationCause::misc(span, def_id);
|
||||||
// FIXME: We should just register the item bounds here, rather than equating.
|
// FIXME: We should just register the item bounds here, rather than equating.
|
||||||
|
// FIXME(const_trait_impl): When we do that, please make sure to also register
|
||||||
|
// the `~const` bounds.
|
||||||
match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
|
match ocx.eq(&misc_cause, param_env, opaque_ty, hidden_ty) {
|
||||||
Ok(()) => {}
|
Ok(()) => {}
|
||||||
Err(ty_err) => {
|
Err(ty_err) => {
|
||||||
|
@ -2083,7 +2083,7 @@ pub(super) fn check_type_bounds<'tcx>(
|
|||||||
// Only in a const implementation do we need to check that the `~const` item bounds hold.
|
// Only in a const implementation do we need to check that the `~const` item bounds hold.
|
||||||
if tcx.is_conditionally_const(impl_ty_def_id) {
|
if tcx.is_conditionally_const(impl_ty_def_id) {
|
||||||
obligations.extend(
|
obligations.extend(
|
||||||
tcx.implied_const_bounds(trait_ty.def_id)
|
tcx.explicit_implied_const_bounds(trait_ty.def_id)
|
||||||
.iter_instantiated_copied(tcx, rebased_args)
|
.iter_instantiated_copied(tcx, rebased_args)
|
||||||
.map(|(c, span)| {
|
.map(|(c, span)| {
|
||||||
traits::Obligation::new(
|
traits::Obligation::new(
|
||||||
|
@ -78,7 +78,7 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
predicates_of::explicit_supertraits_containing_assoc_item,
|
predicates_of::explicit_supertraits_containing_assoc_item,
|
||||||
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
trait_explicit_predicates_and_bounds: predicates_of::trait_explicit_predicates_and_bounds,
|
||||||
const_conditions: predicates_of::const_conditions,
|
const_conditions: predicates_of::const_conditions,
|
||||||
implied_const_bounds: predicates_of::implied_const_bounds,
|
explicit_implied_const_bounds: predicates_of::explicit_implied_const_bounds,
|
||||||
type_param_predicates: predicates_of::type_param_predicates,
|
type_param_predicates: predicates_of::type_param_predicates,
|
||||||
trait_def,
|
trait_def,
|
||||||
adt_def,
|
adt_def,
|
||||||
@ -340,6 +340,10 @@ impl<'tcx> Visitor<'tcx> for CollectItemTypesVisitor<'tcx> {
|
|||||||
self.tcx.ensure().explicit_item_super_predicates(def_id);
|
self.tcx.ensure().explicit_item_super_predicates(def_id);
|
||||||
self.tcx.ensure().item_bounds(def_id);
|
self.tcx.ensure().item_bounds(def_id);
|
||||||
self.tcx.ensure().item_super_predicates(def_id);
|
self.tcx.ensure().item_super_predicates(def_id);
|
||||||
|
if self.tcx.is_conditionally_const(def_id) {
|
||||||
|
self.tcx.ensure().explicit_implied_const_bounds(def_id);
|
||||||
|
self.tcx.ensure().const_conditions(def_id);
|
||||||
|
}
|
||||||
intravisit::walk_opaque_ty(self, opaque);
|
intravisit::walk_opaque_ty(self, opaque);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -682,6 +686,10 @@ fn lower_item(tcx: TyCtxt<'_>, item_id: hir::ItemId) {
|
|||||||
tcx.ensure().generics_of(item.owner_id);
|
tcx.ensure().generics_of(item.owner_id);
|
||||||
tcx.ensure().type_of(item.owner_id);
|
tcx.ensure().type_of(item.owner_id);
|
||||||
tcx.ensure().predicates_of(item.owner_id);
|
tcx.ensure().predicates_of(item.owner_id);
|
||||||
|
if tcx.is_conditionally_const(def_id) {
|
||||||
|
tcx.ensure().explicit_implied_const_bounds(def_id);
|
||||||
|
tcx.ensure().const_conditions(def_id);
|
||||||
|
}
|
||||||
match item.kind {
|
match item.kind {
|
||||||
hir::ForeignItemKind::Fn(..) => {
|
hir::ForeignItemKind::Fn(..) => {
|
||||||
tcx.ensure().codegen_fn_attrs(item.owner_id);
|
tcx.ensure().codegen_fn_attrs(item.owner_id);
|
||||||
|
@ -959,6 +959,12 @@ pub(super) fn const_conditions<'tcx>(
|
|||||||
hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false),
|
hir::ForeignItemKind::Fn(_, _, generics) => (generics, None, false),
|
||||||
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
||||||
},
|
},
|
||||||
|
Node::OpaqueTy(opaque) => match opaque.origin {
|
||||||
|
hir::OpaqueTyOrigin::FnReturn { parent, .. } => return tcx.const_conditions(parent),
|
||||||
|
hir::OpaqueTyOrigin::AsyncFn { .. } | hir::OpaqueTyOrigin::TyAlias { .. } => {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
},
|
||||||
// N.B. Tuple ctors are unconditionally constant.
|
// N.B. Tuple ctors are unconditionally constant.
|
||||||
Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
|
Node::Ctor(hir::VariantData::Tuple { .. }) => return Default::default(),
|
||||||
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
_ => bug!("const_conditions called on wrong item: {def_id:?}"),
|
||||||
@ -1018,7 +1024,7 @@ pub(super) fn const_conditions<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn implied_const_bounds<'tcx>(
|
pub(super) fn explicit_implied_const_bounds<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||||
@ -1034,10 +1040,11 @@ pub(super) fn implied_const_bounds<'tcx>(
|
|||||||
PredicateFilter::SelfConstIfConst,
|
PredicateFilter::SelfConstIfConst,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. }) => {
|
Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Type(..), .. })
|
||||||
|
| Node::OpaqueTy(_) => {
|
||||||
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
|
explicit_item_bounds_with_filter(tcx, def_id, PredicateFilter::ConstIfConst)
|
||||||
}
|
}
|
||||||
_ => bug!("implied_const_bounds called on wrong item: {def_id:?}"),
|
_ => bug!("explicit_implied_const_bounds called on wrong item: {def_id:?}"),
|
||||||
};
|
};
|
||||||
|
|
||||||
bounds.map_bound(|bounds| {
|
bounds.map_bound(|bounds| {
|
||||||
|
@ -574,9 +574,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
// unexpected region errors.
|
// unexpected region errors.
|
||||||
goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));
|
goals.push(Goal::new(tcx, param_env, ty::ClauseKind::WellFormed(hidden_ty.into())));
|
||||||
|
|
||||||
let item_bounds = tcx.explicit_item_bounds(def_id);
|
let replace_opaques_in = |clause: ty::Clause<'tcx>, goals: &mut Vec<_>| {
|
||||||
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
clause.fold_with(&mut BottomUpFolder {
|
||||||
let predicate = predicate.fold_with(&mut BottomUpFolder {
|
|
||||||
tcx,
|
tcx,
|
||||||
ty_op: |ty| match *ty.kind() {
|
ty_op: |ty| match *ty.kind() {
|
||||||
// We can't normalize associated types from `rustc_infer`,
|
// We can't normalize associated types from `rustc_infer`,
|
||||||
@ -612,11 +611,31 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||||||
},
|
},
|
||||||
lt_op: |lt| lt,
|
lt_op: |lt| lt,
|
||||||
ct_op: |ct| ct,
|
ct_op: |ct| ct,
|
||||||
});
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let item_bounds = tcx.explicit_item_bounds(def_id);
|
||||||
|
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||||
|
let predicate = replace_opaques_in(predicate, goals);
|
||||||
|
|
||||||
|
// Require that the predicate holds for the concrete type.
|
||||||
|
debug!(?predicate);
|
||||||
|
goals.push(Goal::new(self.tcx, param_env, predicate));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If this opaque is being defined and it's conditionally const,
|
||||||
|
if self.tcx.is_conditionally_const(def_id) {
|
||||||
|
let item_bounds = tcx.explicit_implied_const_bounds(def_id);
|
||||||
|
for (predicate, _) in item_bounds.iter_instantiated_copied(tcx, args) {
|
||||||
|
let predicate = replace_opaques_in(
|
||||||
|
predicate.to_host_effect_clause(self.tcx, ty::BoundConstness::Maybe),
|
||||||
|
goals,
|
||||||
|
);
|
||||||
|
|
||||||
// Require that the predicate holds for the concrete type.
|
// Require that the predicate holds for the concrete type.
|
||||||
debug!(?predicate);
|
debug!(?predicate);
|
||||||
goals.push(Goal::new(self.tcx, param_env, predicate));
|
goals.push(Goal::new(self.tcx, param_env, predicate));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,7 @@ provide! { tcx, def_id, other, cdata,
|
|||||||
defaultness => { table_direct }
|
defaultness => { table_direct }
|
||||||
constness => { table_direct }
|
constness => { table_direct }
|
||||||
const_conditions => { table }
|
const_conditions => { table }
|
||||||
implied_const_bounds => { table_defaulted_array }
|
explicit_implied_const_bounds => { table_defaulted_array }
|
||||||
coerce_unsized_info => {
|
coerce_unsized_info => {
|
||||||
Ok(cdata
|
Ok(cdata
|
||||||
.root
|
.root
|
||||||
|
@ -1463,8 +1463,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
record_array!(self.tables.module_children_non_reexports[def_id] <-
|
||||||
module_children.iter().map(|child| child.res.def_id().index));
|
module_children.iter().map(|child| child.res.def_id().index));
|
||||||
if self.tcx.is_const_trait(def_id) {
|
if self.tcx.is_const_trait(def_id) {
|
||||||
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||||
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let DefKind::TraitAlias = def_kind {
|
if let DefKind::TraitAlias = def_kind {
|
||||||
@ -1532,6 +1532,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
self.encode_explicit_item_super_predicates(def_id);
|
self.encode_explicit_item_super_predicates(def_id);
|
||||||
record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id));
|
record!(self.tables.opaque_ty_origin[def_id] <- self.tcx.opaque_ty_origin(def_id));
|
||||||
self.encode_precise_capturing_args(def_id);
|
self.encode_precise_capturing_args(def_id);
|
||||||
|
if tcx.is_conditionally_const(def_id) {
|
||||||
|
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||||
|
<- tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
|
if tcx.impl_method_has_trait_impl_trait_tys(def_id)
|
||||||
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
&& let Ok(table) = self.tcx.collect_return_position_impl_trait_in_trait_tys(def_id)
|
||||||
@ -1654,8 +1658,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
|
|||||||
self.encode_explicit_item_bounds(def_id);
|
self.encode_explicit_item_bounds(def_id);
|
||||||
self.encode_explicit_item_super_predicates(def_id);
|
self.encode_explicit_item_super_predicates(def_id);
|
||||||
if tcx.is_conditionally_const(def_id) {
|
if tcx.is_conditionally_const(def_id) {
|
||||||
record_defaulted_array!(self.tables.implied_const_bounds[def_id]
|
record_defaulted_array!(self.tables.explicit_implied_const_bounds[def_id]
|
||||||
<- self.tcx.implied_const_bounds(def_id).skip_binder());
|
<- self.tcx.explicit_implied_const_bounds(def_id).skip_binder());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,7 +391,7 @@ define_tables! {
|
|||||||
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
inferred_outlives_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
explicit_super_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
explicit_implied_predicates_of: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
|
||||||
implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
|
explicit_implied_const_bounds: Table<DefIndex, LazyArray<(ty::PolyTraitRef<'static>, Span)>>,
|
||||||
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
|
inherent_impls: Table<DefIndex, LazyArray<DefIndex>>,
|
||||||
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
|
associated_types_for_impl_traits_in_associated_fn: Table<DefIndex, LazyArray<DefId>>,
|
||||||
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
|
opt_rpitit_info: Table<DefIndex, Option<LazyValue<ty::ImplTraitInTraitData>>>,
|
||||||
|
@ -697,7 +697,7 @@ rustc_queries! {
|
|||||||
separate_provide_extern
|
separate_provide_extern
|
||||||
}
|
}
|
||||||
|
|
||||||
query implied_const_bounds(
|
query explicit_implied_const_bounds(
|
||||||
key: DefId
|
key: DefId
|
||||||
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
) -> ty::EarlyBinder<'tcx, &'tcx [(ty::PolyTraitRef<'tcx>, Span)]> {
|
||||||
desc { |tcx| "computing the implied `~const` bounds for `{}`",
|
desc { |tcx| "computing the implied `~const` bounds for `{}`",
|
||||||
|
@ -393,12 +393,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn implied_const_bounds(
|
fn explicit_implied_const_bounds(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
|
||||||
ty::EarlyBinder::bind(
|
ty::EarlyBinder::bind(
|
||||||
self.implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2110,7 +2110,13 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||||||
_ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
|
_ => bug!("unexpected parent item of associated item: {parent_def_id:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DefKind::Closure | DefKind::OpaqueTy => {
|
DefKind::OpaqueTy => match self.opaque_ty_origin(def_id) {
|
||||||
|
hir::OpaqueTyOrigin::FnReturn { parent, .. } => self.is_conditionally_const(parent),
|
||||||
|
hir::OpaqueTyOrigin::AsyncFn { .. } => false,
|
||||||
|
// FIXME(const_trait_impl): ATPITs could be conditionally const?
|
||||||
|
hir::OpaqueTyOrigin::TyAlias { .. } => false,
|
||||||
|
},
|
||||||
|
DefKind::Closure => {
|
||||||
// Closures and RPITs will eventually have const conditions
|
// Closures and RPITs will eventually have const conditions
|
||||||
// for `~const` bounds.
|
// for `~const` bounds.
|
||||||
false
|
false
|
||||||
|
@ -102,7 +102,7 @@ where
|
|||||||
|
|
||||||
/// Assemble additional assumptions for an alias that are not included
|
/// Assemble additional assumptions for an alias that are not included
|
||||||
/// in the item bounds of the alias. For now, this is limited to the
|
/// in the item bounds of the alias. For now, this is limited to the
|
||||||
/// `implied_const_bounds` for an associated type.
|
/// `explicit_implied_const_bounds` for an associated type.
|
||||||
fn consider_additional_alias_assumptions(
|
fn consider_additional_alias_assumptions(
|
||||||
ecx: &mut EvalCtxt<'_, D>,
|
ecx: &mut EvalCtxt<'_, D>,
|
||||||
goal: Goal<I, Self>,
|
goal: Goal<I, Self>,
|
||||||
|
@ -84,12 +84,9 @@ where
|
|||||||
let cx = ecx.cx();
|
let cx = ecx.cx();
|
||||||
let mut candidates = vec![];
|
let mut candidates = vec![];
|
||||||
|
|
||||||
// FIXME(const_trait_impl): We elaborate here because the implied const bounds
|
|
||||||
// aren't necessarily elaborated. We probably should prefix this query
|
|
||||||
// with `explicit_`...
|
|
||||||
for clause in elaborate::elaborate(
|
for clause in elaborate::elaborate(
|
||||||
cx,
|
cx,
|
||||||
cx.implied_const_bounds(alias_ty.def_id)
|
cx.explicit_implied_const_bounds(alias_ty.def_id)
|
||||||
.iter_instantiated(cx, alias_ty.args)
|
.iter_instantiated(cx, alias_ty.args)
|
||||||
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
|
.map(|trait_ref| trait_ref.to_host_effect_clause(cx, goal.predicate.constness)),
|
||||||
) {
|
) {
|
||||||
|
@ -157,7 +157,7 @@ impl<I: Interner, O: Elaboratable<I>> Elaborator<I, O> {
|
|||||||
}
|
}
|
||||||
// `T: ~const Trait` implies `T: ~const Supertrait`.
|
// `T: ~const Trait` implies `T: ~const Supertrait`.
|
||||||
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
|
ty::ClauseKind::HostEffect(data) => self.extend_deduped(
|
||||||
cx.implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
|
cx.explicit_implied_const_bounds(data.def_id()).iter_identity().map(|trait_ref| {
|
||||||
elaboratable.child(
|
elaboratable.child(
|
||||||
trait_ref
|
trait_ref
|
||||||
.to_host_effect_clause(cx, data.constness)
|
.to_host_effect_clause(cx, data.constness)
|
||||||
|
@ -229,7 +229,7 @@ pub trait Interner:
|
|||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||||
fn implied_const_bounds(
|
fn explicit_implied_const_bounds(
|
||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
) -> ty::EarlyBinder<Self, impl IntoIterator<Item = ty::Binder<Self, ty::TraitRef<Self>>>>;
|
||||||
|
@ -12,5 +12,13 @@ LL | const fn test() -> impl ~const Fn() {
|
|||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/const-closure-parse-not-item.rs:7:25
|
||||||
|
|
|
||||||
|
LL | const fn test() -> impl ~const Fn() {
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
15
tests/ui/traits/const-traits/const-opaque.no.stderr
Normal file
15
tests/ui/traits/const-traits/const-opaque.no.stderr
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
error[E0277]: the trait bound `(): const Foo` is not satisfied
|
||||||
|
--> $DIR/const-opaque.rs:31:18
|
||||||
|
|
|
||||||
|
LL | let opaque = bar(());
|
||||||
|
| ^^^^^^^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `(): const Foo` is not satisfied
|
||||||
|
--> $DIR/const-opaque.rs:33:5
|
||||||
|
|
|
||||||
|
LL | opaque.method();
|
||||||
|
| ^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0277`.
|
38
tests/ui/traits/const-traits/const-opaque.rs
Normal file
38
tests/ui/traits/const-traits/const-opaque.rs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
//@ revisions: yes no
|
||||||
|
//@ compile-flags: -Znext-solver
|
||||||
|
//@[yes] check-pass
|
||||||
|
|
||||||
|
#![feature(const_trait_impl)]
|
||||||
|
|
||||||
|
#[const_trait]
|
||||||
|
trait Foo {
|
||||||
|
fn method(&self);
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: ~const Foo> const Foo for (T,) {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(yes)]
|
||||||
|
impl const Foo for () {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(no)]
|
||||||
|
impl Foo for () {
|
||||||
|
fn method(&self) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
const fn bar<T: ~const Foo>(t: T) -> impl ~const Foo {
|
||||||
|
(t,)
|
||||||
|
}
|
||||||
|
|
||||||
|
const _: () = {
|
||||||
|
let opaque = bar(());
|
||||||
|
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
|
||||||
|
opaque.method();
|
||||||
|
//[no]~^ ERROR the trait bound `(): const Foo` is not satisfied
|
||||||
|
std::mem::forget(opaque);
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
@ -3,6 +3,7 @@
|
|||||||
const fn test() -> impl ~const Fn() {
|
const fn test() -> impl ~const Fn() {
|
||||||
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
|
//~^ ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||||
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
|
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
//~| ERROR `~const` can only be applied to `#[const_trait]` traits
|
||||||
const move || { //~ ERROR const closures are experimental
|
const move || { //~ ERROR const closures are experimental
|
||||||
let sl: &[u8] = b"foo";
|
let sl: &[u8] = b"foo";
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
error[E0658]: const closures are experimental
|
error[E0658]: const closures are experimental
|
||||||
--> $DIR/ice-112822-expected-type-for-param.rs:6:5
|
--> $DIR/ice-112822-expected-type-for-param.rs:7:5
|
||||||
|
|
|
|
||||||
LL | const move || {
|
LL | const move || {
|
||||||
| ^^^^^
|
| ^^^^^
|
||||||
@ -22,8 +22,16 @@ LL | const fn test() -> impl ~const Fn() {
|
|||||||
|
|
|
|
||||||
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
|
error: `~const` can only be applied to `#[const_trait]` traits
|
||||||
|
--> $DIR/ice-112822-expected-type-for-param.rs:3:25
|
||||||
|
|
|
||||||
|
LL | const fn test() -> impl ~const Fn() {
|
||||||
|
| ^^^^^^
|
||||||
|
|
|
||||||
|
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
|
||||||
|
|
||||||
error[E0015]: cannot call non-const operator in constant functions
|
error[E0015]: cannot call non-const operator in constant functions
|
||||||
--> $DIR/ice-112822-expected-type-for-param.rs:11:17
|
--> $DIR/ice-112822-expected-type-for-param.rs:12:17
|
||||||
|
|
|
|
||||||
LL | assert_eq!(first, &b'f');
|
LL | assert_eq!(first, &b'f');
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -32,7 +40,7 @@ LL | assert_eq!(first, &b'f');
|
|||||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error[E0015]: cannot call non-const fn `core::panicking::assert_failed::<&u8, &u8>` in constant functions
|
error[E0015]: cannot call non-const fn `core::panicking::assert_failed::<&u8, &u8>` in constant functions
|
||||||
--> $DIR/ice-112822-expected-type-for-param.rs:11:17
|
--> $DIR/ice-112822-expected-type-for-param.rs:12:17
|
||||||
|
|
|
|
||||||
LL | assert_eq!(first, &b'f');
|
LL | assert_eq!(first, &b'f');
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
@ -40,7 +48,7 @@ LL | assert_eq!(first, &b'f');
|
|||||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||||
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
= note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||||
|
|
||||||
error: aborting due to 5 previous errors
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
Some errors have detailed explanations: E0015, E0658.
|
Some errors have detailed explanations: E0015, E0658.
|
||||||
For more information about an error, try `rustc --explain E0015`.
|
For more information about an error, try `rustc --explain E0015`.
|
||||||
|
Loading…
Reference in New Issue
Block a user