mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 05:56:56 +00:00
Enforce syntactical stability of const traits in HIR
This commit is contained in:
parent
8c39ce5b4f
commit
2743df848b
@ -30,6 +30,14 @@ pub enum StabilityLevel {
|
||||
Stable,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum UnstableKind {
|
||||
/// Enforcing regular stability of an item
|
||||
Regular,
|
||||
/// Enforcing const stability of an item
|
||||
Const(Span),
|
||||
}
|
||||
|
||||
/// An entry in the `depr_map`.
|
||||
#[derive(Copy, Clone, HashStable, Debug, Encodable, Decodable)]
|
||||
pub struct DeprecationEntry {
|
||||
@ -108,10 +116,16 @@ pub fn report_unstable(
|
||||
is_soft: bool,
|
||||
span: Span,
|
||||
soft_handler: impl FnOnce(&'static Lint, Span, String),
|
||||
kind: UnstableKind,
|
||||
) {
|
||||
let qual = match kind {
|
||||
UnstableKind::Regular => "",
|
||||
UnstableKind::Const(_) => " const",
|
||||
};
|
||||
|
||||
let msg = match reason {
|
||||
Some(r) => format!("use of unstable library feature `{feature}`: {r}"),
|
||||
None => format!("use of unstable library feature `{feature}`"),
|
||||
Some(r) => format!("use of unstable{qual} library feature `{feature}`: {r}"),
|
||||
None => format!("use of unstable{qual} library feature `{feature}`"),
|
||||
};
|
||||
|
||||
if is_soft {
|
||||
@ -121,6 +135,9 @@ pub fn report_unstable(
|
||||
if let Some((inner_types, msg, sugg, applicability)) = suggestion {
|
||||
err.span_suggestion(inner_types, msg, sugg, applicability);
|
||||
}
|
||||
if let UnstableKind::Const(kw) = kind {
|
||||
err.span_label(kw, "trait is not stable as const yet");
|
||||
}
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
@ -587,6 +604,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
is_soft,
|
||||
span,
|
||||
soft_handler,
|
||||
UnstableKind::Regular,
|
||||
),
|
||||
EvalResult::Unmarked => unmarked(span, def_id),
|
||||
}
|
||||
@ -594,6 +612,73 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
is_allowed
|
||||
}
|
||||
|
||||
/// This function is analogous to `check_optional_stability` but with the logic in
|
||||
/// `eval_stability_allow_unstable` inlined, and which operating on const stability
|
||||
/// instead of regular stability.
|
||||
///
|
||||
/// This enforces *syntactical* const stability of const traits. In other words,
|
||||
/// it enforces the ability to name `~const`/`const` traits in trait bounds in various
|
||||
/// syntax positions in HIR (including in the trait of an impl header).
|
||||
pub fn check_const_stability(self, def_id: DefId, span: Span, const_kw_span: Span) {
|
||||
let is_staged_api = self.lookup_stability(def_id.krate.as_def_id()).is_some();
|
||||
if !is_staged_api {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only the cross-crate scenario matters when checking unstable APIs
|
||||
let cross_crate = !def_id.is_local();
|
||||
if !cross_crate {
|
||||
return;
|
||||
}
|
||||
|
||||
let stability = self.lookup_const_stability(def_id);
|
||||
debug!(
|
||||
"stability: \
|
||||
inspecting def_id={:?} span={:?} of stability={:?}",
|
||||
def_id, span, stability
|
||||
);
|
||||
|
||||
match stability {
|
||||
Some(ConstStability {
|
||||
level: attr::StabilityLevel::Unstable { reason, issue, is_soft, implied_by, .. },
|
||||
feature,
|
||||
..
|
||||
}) => {
|
||||
assert!(!is_soft);
|
||||
|
||||
if span.allows_unstable(feature) {
|
||||
debug!("body stability: skipping span={:?} since it is internal", span);
|
||||
return;
|
||||
}
|
||||
if self.features().enabled(feature) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If this item was previously part of a now-stabilized feature which is still
|
||||
// enabled (i.e. the user hasn't removed the attribute for the stabilized feature
|
||||
// yet) then allow use of this item.
|
||||
if let Some(implied_by) = implied_by
|
||||
&& self.features().enabled(implied_by)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
report_unstable(
|
||||
self.sess,
|
||||
feature,
|
||||
reason.to_opt_reason(),
|
||||
issue,
|
||||
None,
|
||||
false,
|
||||
span,
|
||||
|_, _, _| {},
|
||||
UnstableKind::Const(const_kw_span),
|
||||
);
|
||||
}
|
||||
Some(_) | None => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
|
||||
self.lookup_deprecation_entry(id).map(|depr| depr.attr)
|
||||
}
|
||||
|
@ -593,9 +593,11 @@ impl<'tcx> MissingStabilityAnnotations<'tcx> {
|
||||
}
|
||||
|
||||
fn check_missing_const_stability(&self, def_id: LocalDefId, span: Span) {
|
||||
let is_const = self.tcx.is_const_fn(def_id.to_def_id());
|
||||
let is_const = self.tcx.is_const_fn(def_id.to_def_id())
|
||||
|| (self.tcx.def_kind(def_id.to_def_id()) == DefKind::Trait
|
||||
&& self.tcx.is_const_trait(def_id.to_def_id()));
|
||||
|
||||
// Reachable const fn must have a stability attribute.
|
||||
// Reachable const fn/trait must have a stability attribute.
|
||||
if is_const
|
||||
&& self.effective_visibilities.is_reachable(def_id)
|
||||
&& self.tcx.lookup_const_stability(def_id).is_none()
|
||||
@ -772,7 +774,13 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||
// For implementations of traits, check the stability of each item
|
||||
// individually as it's possible to have a stable trait with unstable
|
||||
// items.
|
||||
hir::ItemKind::Impl(hir::Impl { of_trait: Some(ref t), self_ty, items, .. }) => {
|
||||
hir::ItemKind::Impl(hir::Impl {
|
||||
of_trait: Some(ref t),
|
||||
self_ty,
|
||||
items,
|
||||
constness,
|
||||
..
|
||||
}) => {
|
||||
let features = self.tcx.features();
|
||||
if features.staged_api() {
|
||||
let attrs = self.tcx.hir().attrs(item.hir_id());
|
||||
@ -814,6 +822,16 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
match constness {
|
||||
rustc_hir::Constness::Const => {
|
||||
if let Some(def_id) = t.trait_def_id() {
|
||||
// FIXME(const_trait_impl): Improve the span here.
|
||||
self.tcx.check_const_stability(def_id, t.path.span, t.path.span);
|
||||
}
|
||||
}
|
||||
rustc_hir::Constness::NotConst => {}
|
||||
}
|
||||
|
||||
for impl_item_ref in *items {
|
||||
let impl_item = self.tcx.associated_item(impl_item_ref.id.owner_id);
|
||||
|
||||
@ -829,6 +847,18 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||
intravisit::walk_item(self, item);
|
||||
}
|
||||
|
||||
fn visit_poly_trait_ref(&mut self, t: &'tcx hir::PolyTraitRef<'tcx>) {
|
||||
match t.modifiers.constness {
|
||||
hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) => {
|
||||
if let Some(def_id) = t.trait_ref.trait_def_id() {
|
||||
self.tcx.check_const_stability(def_id, t.trait_ref.path.span, span);
|
||||
}
|
||||
}
|
||||
hir::BoundConstness::Never => {}
|
||||
}
|
||||
intravisit::walk_poly_trait_ref(self, t);
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &hir::Path<'tcx>, id: hir::HirId) {
|
||||
if let Some(def_id) = path.res.opt_def_id() {
|
||||
let method_span = path.segments.last().map(|s| s.ident.span);
|
||||
|
@ -1031,6 +1031,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
|
||||
is_soft,
|
||||
span,
|
||||
soft_handler,
|
||||
stability::UnstableKind::Regular,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
#![allow(missing_docs)]
|
||||
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "core_intrinsics_fallbacks", issue = "none")]
|
||||
pub trait CarryingMulAdd: Copy + 'static {
|
||||
type Unsigned: Copy + 'static;
|
||||
fn carrying_mul_add(
|
||||
|
@ -952,6 +952,7 @@ marker_impls! {
|
||||
/// This should be used for `~const` bounds,
|
||||
/// as non-const bounds will always hold for every type.
|
||||
#[unstable(feature = "const_destruct", issue = "133214")]
|
||||
#[rustc_const_unstable(feature = "const_destruct", issue = "133214")]
|
||||
#[lang = "destruct"]
|
||||
#[rustc_on_unimplemented(message = "can't drop `{Self}`", append_const_msg)]
|
||||
#[rustc_deny_explicit_impl]
|
||||
|
@ -65,6 +65,7 @@
|
||||
/// ```
|
||||
#[lang = "add"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_ops", issue = "90080")]
|
||||
#[rustc_on_unimplemented(
|
||||
on(all(_Self = "{integer}", Rhs = "{float}"), message = "cannot add a float to an integer",),
|
||||
on(all(_Self = "{float}", Rhs = "{integer}"), message = "cannot add an integer to a float",),
|
||||
|
@ -134,6 +134,7 @@
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_diagnostic_item = "Deref"]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
pub trait Deref {
|
||||
/// The resulting type after dereferencing.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
@ -263,6 +264,7 @@ impl<T: ?Sized> const Deref for &mut T {
|
||||
#[doc(alias = "*")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_deref", issue = "88955")]
|
||||
pub trait DerefMut: ~const Deref {
|
||||
/// Mutably dereferences the value.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -204,6 +204,7 @@
|
||||
#[lang = "drop"]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[const_trait]
|
||||
#[rustc_const_unstable(feature = "const_destruct", issue = "133214")]
|
||||
pub trait Drop {
|
||||
/// Executes the destructor for this type.
|
||||
///
|
||||
|
@ -1,4 +1,4 @@
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, const_destruct)]
|
||||
|
||||
struct A();
|
||||
|
||||
|
@ -1,6 +1,4 @@
|
||||
//@ known-bug: #103507
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, const_destruct)]
|
||||
|
||||
struct Panic;
|
||||
impl const Drop for Panic { fn drop(&mut self) { panic!(); } }
|
||||
@ -8,15 +6,15 @@ impl const Drop for Panic { fn drop(&mut self) { panic!(); } }
|
||||
pub const fn id<T>(x: T) -> T { x }
|
||||
pub const C: () = {
|
||||
let _: &'static _ = &id(&Panic);
|
||||
//FIXME ~^ ERROR: temporary value dropped while borrowed
|
||||
//FIXME ~| ERROR: temporary value dropped while borrowed
|
||||
//~^ ERROR: temporary value dropped while borrowed
|
||||
//~| ERROR: temporary value dropped while borrowed
|
||||
};
|
||||
|
||||
fn main() {
|
||||
let _: &'static _ = &id(&Panic);
|
||||
//FIXME ~^ ERROR: temporary value dropped while borrowed
|
||||
//FIXME ~| ERROR: temporary value dropped while borrowed
|
||||
//~^ ERROR: temporary value dropped while borrowed
|
||||
//~| ERROR: temporary value dropped while borrowed
|
||||
let _: &'static _ = &&(Panic, 0).1;
|
||||
//FIXME~^ ERROR: temporary value dropped while borrowed
|
||||
//FIXME~| ERROR: temporary value dropped while borrowed
|
||||
//~^ ERROR: temporary value dropped while borrowed
|
||||
//~| ERROR: temporary value dropped while borrowed
|
||||
}
|
||||
|
@ -1,17 +1,25 @@
|
||||
error[E0493]: destructor of `Panic` cannot be evaluated at compile-time
|
||||
--> $DIR/promoted_const_call.rs:10:30
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promoted_const_call.rs:8:26
|
||||
|
|
||||
LL | let _: &'static _ = &id(&Panic);
|
||||
| ^^^^^ - value is dropped here
|
||||
| |
|
||||
| the destructor for this type cannot be evaluated in constants
|
||||
|
|
||||
= note: see issue #133214 <https://github.com/rust-lang/rust/issues/133214> for more information
|
||||
= help: add `#![feature(const_destruct)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||
| |
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
...
|
||||
LL | };
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promoted_const_call.rs:16:26
|
||||
--> $DIR/promoted_const_call.rs:8:30
|
||||
|
|
||||
LL | let _: &'static _ = &id(&Panic);
|
||||
| ---------- ^^^^^ - temporary value is freed at the end of this statement
|
||||
| | |
|
||||
| | creates a temporary value which is freed while still in use
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promoted_const_call.rs:14:26
|
||||
|
|
||||
LL | let _: &'static _ = &id(&Panic);
|
||||
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||
@ -22,7 +30,7 @@ LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promoted_const_call.rs:16:30
|
||||
--> $DIR/promoted_const_call.rs:14:30
|
||||
|
|
||||
LL | let _: &'static _ = &id(&Panic);
|
||||
| ---------- ^^^^^ - temporary value is freed at the end of this statement
|
||||
@ -31,7 +39,7 @@ LL | let _: &'static _ = &id(&Panic);
|
||||
| type annotation requires that borrow lasts for `'static`
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promoted_const_call.rs:19:26
|
||||
--> $DIR/promoted_const_call.rs:17:26
|
||||
|
|
||||
LL | let _: &'static _ = &&(Panic, 0).1;
|
||||
| ---------- ^^^^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||
@ -42,7 +50,7 @@ LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error[E0716]: temporary value dropped while borrowed
|
||||
--> $DIR/promoted_const_call.rs:19:27
|
||||
--> $DIR/promoted_const_call.rs:17:27
|
||||
|
|
||||
LL | let _: &'static _ = &&(Panic, 0).1;
|
||||
| ---------- ^^^^^^^^^^ creates a temporary value which is freed while still in use
|
||||
@ -52,7 +60,6 @@ LL | let _: &'static _ = &&(Panic, 0).1;
|
||||
LL | }
|
||||
| - temporary value is freed at the end of this statement
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0493, E0716.
|
||||
For more information about an error, try `rustc --explain E0493`.
|
||||
For more information about this error, try `rustc --explain E0716`.
|
||||
|
@ -22,6 +22,7 @@ impl Foo {
|
||||
#[stable(feature = "stable", since = "1.0.0")]
|
||||
#[const_trait]
|
||||
pub trait Bar {
|
||||
//~^ ERROR trait has missing const stability attribute
|
||||
#[stable(feature = "stable", since = "1.0.0")]
|
||||
fn fun();
|
||||
}
|
||||
|
@ -4,8 +4,18 @@ error: function has missing const stability attribute
|
||||
LL | pub const fn foo() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: trait has missing const stability attribute
|
||||
--> $DIR/missing-const-stability.rs:24:1
|
||||
|
|
||||
LL | / pub trait Bar {
|
||||
LL | |
|
||||
LL | | #[stable(feature = "stable", since = "1.0.0")]
|
||||
LL | | fn fun();
|
||||
LL | | }
|
||||
| |_^
|
||||
|
||||
error: function has missing const stability attribute
|
||||
--> $DIR/missing-const-stability.rs:36:1
|
||||
--> $DIR/missing-const-stability.rs:37:1
|
||||
|
|
||||
LL | pub const unsafe fn size_of_val<T>(x: *const T) -> usize { 42 }
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -16,5 +26,5 @@ error: associated function has missing const stability attribute
|
||||
LL | pub const fn foo() {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
|
@ -4,6 +4,7 @@
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "unstable", issue = "none")]
|
||||
#[const_trait]
|
||||
pub trait MyTrait {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ known-bug: #110395
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, const_ops)]
|
||||
|
||||
struct Int(i32);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ known-bug: #110395
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, const_ops)]
|
||||
|
||||
pub struct Int(i32);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
//@ check-pass
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(const_trait_impl, const_ops)]
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
|
34
tests/ui/traits/const-traits/syntactical-unstable.rs
Normal file
34
tests/ui/traits/const-traits/syntactical-unstable.rs
Normal file
@ -0,0 +1,34 @@
|
||||
//@ aux-build:staged-api.rs
|
||||
|
||||
// Ensure that we enforce const stability of traits in `~const`/`const` bounds.
|
||||
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
use std::ops::Deref;
|
||||
|
||||
extern crate staged_api;
|
||||
use staged_api::MyTrait;
|
||||
|
||||
#[const_trait]
|
||||
trait Foo: ~const MyTrait {
|
||||
//~^ ERROR use of unstable const library feature `unstable`
|
||||
type Item: ~const MyTrait;
|
||||
//~^ ERROR use of unstable const library feature `unstable`
|
||||
}
|
||||
|
||||
const fn where_clause<T>() where T: ~const MyTrait {}
|
||||
//~^ ERROR use of unstable const library feature `unstable`
|
||||
|
||||
const fn nested<T>() where T: Deref<Target: ~const MyTrait> {}
|
||||
//~^ ERROR use of unstable const library feature `unstable`
|
||||
|
||||
const fn rpit() -> impl ~const MyTrait { Local }
|
||||
//~^ ERROR use of unstable const library feature `unstable`
|
||||
|
||||
struct Local;
|
||||
impl const MyTrait for Local {
|
||||
//~^ ERROR use of unstable const library feature `unstable`
|
||||
fn func() {}
|
||||
}
|
||||
|
||||
fn main() {}
|
67
tests/ui/traits/const-traits/syntactical-unstable.stderr
Normal file
67
tests/ui/traits/const-traits/syntactical-unstable.stderr
Normal file
@ -0,0 +1,67 @@
|
||||
error[E0658]: use of unstable const library feature `unstable`
|
||||
--> $DIR/syntactical-unstable.rs:13:19
|
||||
|
|
||||
LL | trait Foo: ~const MyTrait {
|
||||
| ------ ^^^^^^^
|
||||
| |
|
||||
| trait is not stable as const yet
|
||||
|
|
||||
= help: add `#![feature(unstable)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable const library feature `unstable`
|
||||
--> $DIR/syntactical-unstable.rs:19:44
|
||||
|
|
||||
LL | const fn where_clause<T>() where T: ~const MyTrait {}
|
||||
| ------ ^^^^^^^
|
||||
| |
|
||||
| trait is not stable as const yet
|
||||
|
|
||||
= help: add `#![feature(unstable)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable const library feature `unstable`
|
||||
--> $DIR/syntactical-unstable.rs:22:52
|
||||
|
|
||||
LL | const fn nested<T>() where T: Deref<Target: ~const MyTrait> {}
|
||||
| ------ ^^^^^^^
|
||||
| |
|
||||
| trait is not stable as const yet
|
||||
|
|
||||
= help: add `#![feature(unstable)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable const library feature `unstable`
|
||||
--> $DIR/syntactical-unstable.rs:25:32
|
||||
|
|
||||
LL | const fn rpit() -> impl ~const MyTrait { Local }
|
||||
| ------ ^^^^^^^
|
||||
| |
|
||||
| trait is not stable as const yet
|
||||
|
|
||||
= help: add `#![feature(unstable)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable const library feature `unstable`
|
||||
--> $DIR/syntactical-unstable.rs:29:12
|
||||
|
|
||||
LL | impl const MyTrait for Local {
|
||||
| ^^^^^^^ trait is not stable as const yet
|
||||
|
|
||||
= help: add `#![feature(unstable)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error[E0658]: use of unstable const library feature `unstable`
|
||||
--> $DIR/syntactical-unstable.rs:15:23
|
||||
|
|
||||
LL | type Item: ~const MyTrait;
|
||||
| ------ ^^^^^^^
|
||||
| |
|
||||
| trait is not stable as const yet
|
||||
|
|
||||
= help: add `#![feature(unstable)]` to the crate attributes to enable
|
||||
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
@ -38,6 +38,7 @@ impl const FromResidual for T {
|
||||
}
|
||||
|
||||
#[stable(feature = "foo", since = "1.0")]
|
||||
#[rustc_const_unstable(feature = "const_tr", issue = "none")]
|
||||
#[const_trait]
|
||||
pub trait Tr {
|
||||
#[stable(feature = "foo", since = "1.0")]
|
||||
|
@ -17,7 +17,7 @@ LL | impl const FromResidual for T {
|
||||
= note: adding a non-const method body in the future would be a breaking change
|
||||
|
||||
error[E0015]: `?` is not allowed on `T` in constant functions
|
||||
--> $DIR/trait-default-body-stability.rs:45:9
|
||||
--> $DIR/trait-default-body-stability.rs:46:9
|
||||
|
|
||||
LL | T?
|
||||
| ^^
|
||||
@ -25,7 +25,7 @@ LL | T?
|
||||
= note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
|
||||
|
||||
error[E0015]: `?` is not allowed on `T` in constant functions
|
||||
--> $DIR/trait-default-body-stability.rs:45:9
|
||||
--> $DIR/trait-default-body-stability.rs:46:9
|
||||
|
|
||||
LL | T?
|
||||
| ^^
|
||||
|
Loading…
Reference in New Issue
Block a user