Rollup merge of #135423 - compiler-errors:enforce-const-trait-syntactical, r=oli-obk,RalfJung
Enforce syntactical stability of const traits in HIR This PR enforces what I'm calling *syntactical* const stability of 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). This functionality is analogous to the *regular* item stability checker, which is concerned with making sure that you cannot refer to unstable items by name, and is implemented as an extension of that pass. This is separate from enforcing the *recursive* const stability of const trait methods, which is implemented in MIR and runs on MIR bodies. That will require adding a new `NonConstOp` to the const checker and probably adjusting some logic to deduplicate redundant errors. However, this check is separate and necessary for making sure that users don't add `~const`/`const` bounds to items when the trait is not const-stable in the first place. I chose to separate enforcing recursive const stability out of this PR to make it easier to review. I'll probably open a follow-up following this one, blocked on this PR. r? `@RalfJung` cc `@rust-lang/project-const-traits`
This commit is contained in:
commit
11ac57af6e
21 changed files with 279 additions and 38 deletions
|
|
@ -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…
Add table
Add a link
Reference in a new issue