mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 05:51:58 +00:00
Support unstable moves via stable in unstable items
This commit is contained in:
parent
052495d001
commit
e7fe5456c5
@ -471,13 +471,15 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
///
|
||||
/// This function will also check if the item is deprecated.
|
||||
/// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
|
||||
///
|
||||
/// Returns `true` if item is allowed aka, stable or unstable under an enabled feature.
|
||||
pub fn check_stability(
|
||||
self,
|
||||
def_id: DefId,
|
||||
id: Option<HirId>,
|
||||
span: Span,
|
||||
method_span: Option<Span>,
|
||||
) {
|
||||
) -> bool {
|
||||
self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
|
||||
}
|
||||
|
||||
@ -497,7 +499,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
span: Span,
|
||||
method_span: Option<Span>,
|
||||
allow_unstable: AllowUnstable,
|
||||
) {
|
||||
) -> bool {
|
||||
self.check_optional_stability(
|
||||
def_id,
|
||||
id,
|
||||
@ -516,6 +518,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
/// missing stability attributes (not necessarily just emit a `bug!`). This is necessary
|
||||
/// for default generic parameters, which only have stability attributes if they were
|
||||
/// added after the type on which they're defined.
|
||||
///
|
||||
/// Returns `true` if item is allowed aka, stable or unstable under an enabled feature.
|
||||
pub fn check_optional_stability(
|
||||
self,
|
||||
def_id: DefId,
|
||||
@ -524,13 +528,16 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
method_span: Option<Span>,
|
||||
allow_unstable: AllowUnstable,
|
||||
unmarked: impl FnOnce(Span, DefId),
|
||||
) {
|
||||
) -> bool {
|
||||
let soft_handler = |lint, span, msg: &_| {
|
||||
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
|
||||
lint.build(msg).emit();
|
||||
})
|
||||
};
|
||||
match self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable) {
|
||||
let eval_result =
|
||||
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
|
||||
let is_allowed = matches!(eval_result, EvalResult::Allow);
|
||||
match eval_result {
|
||||
EvalResult::Allow => {}
|
||||
EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable(
|
||||
self.sess,
|
||||
@ -544,6 +551,8 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
),
|
||||
EvalResult::Unmarked => unmarked(span, def_id),
|
||||
}
|
||||
|
||||
is_allowed
|
||||
}
|
||||
|
||||
pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {
|
||||
|
@ -807,7 +807,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||
fn visit_path(&mut self, path: &'tcx 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);
|
||||
self.tcx.check_stability_allow_unstable(
|
||||
let item_is_allowed = self.tcx.check_stability_allow_unstable(
|
||||
def_id,
|
||||
Some(id),
|
||||
path.span,
|
||||
@ -817,8 +817,33 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
|
||||
} else {
|
||||
AllowUnstable::No
|
||||
},
|
||||
)
|
||||
);
|
||||
|
||||
if item_is_allowed {
|
||||
// Check parent modules stability as well
|
||||
//
|
||||
// We check here rather than in `visit_path_segment` to prevent visiting the last
|
||||
// path segment twice
|
||||
let parents = path.segments.iter().rev().skip(1);
|
||||
for path_segment in parents {
|
||||
if let Some(def_id) = path_segment.res.as_ref().and_then(Res::opt_def_id) {
|
||||
// use `None` for id to prevent deprecation check
|
||||
self.tcx.check_stability_allow_unstable(
|
||||
def_id,
|
||||
None,
|
||||
path.span,
|
||||
None,
|
||||
if is_unstable_reexport(self.tcx, id) {
|
||||
AllowUnstable::Yes
|
||||
} else {
|
||||
AllowUnstable::No
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
intravisit::walk_path(self, path)
|
||||
}
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||
// as the rest of the type. As such, we ignore missing
|
||||
// stability attributes.
|
||||
},
|
||||
)
|
||||
);
|
||||
}
|
||||
if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) {
|
||||
self.inferred_params.push(ty.span);
|
||||
|
@ -2649,6 +2649,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
|
||||
/// Here is an example of how this could cause a problem:
|
||||
/// ```no_run
|
||||
/// #![feature(const_eval_select)]
|
||||
/// #![feature(core_intrinsics)]
|
||||
/// use std::hint::unreachable_unchecked;
|
||||
/// use std::intrinsics::const_eval_select;
|
||||
///
|
||||
|
@ -1,7 +1,9 @@
|
||||
#![unstable(feature = "unicode_internals", issue = "none")]
|
||||
#![stable(feature = "unicode_version", since = "1.45.0")]
|
||||
#![allow(missing_docs)]
|
||||
|
||||
#[unstable(feature = "unicode_internals", issue = "none")]
|
||||
pub(crate) mod printable;
|
||||
#[unstable(feature = "unicode_internals", issue = "none")]
|
||||
mod unicode_data;
|
||||
|
||||
/// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
|
||||
@ -18,6 +20,7 @@ mod unicode_data;
|
||||
pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION;
|
||||
|
||||
// For use in liballoc, not re-exported in libstd.
|
||||
#[unstable(feature = "unicode_internals", issue = "none")]
|
||||
pub use unicode_data::{
|
||||
case_ignorable::lookup as Case_Ignorable, cased::lookup as Cased, conversions,
|
||||
};
|
||||
|
@ -214,7 +214,7 @@
|
||||
#![cfg_attr(not(bootstrap), deny(ffi_unwind_calls))]
|
||||
// std may use features in a platform-specific way
|
||||
#![allow(unused_features)]
|
||||
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count))]
|
||||
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
|
||||
#![cfg_attr(
|
||||
all(target_vendor = "fortanix", target_env = "sgx"),
|
||||
feature(slice_index_methods, coerce_unsized, sgx_platform)
|
||||
@ -297,6 +297,7 @@
|
||||
// Library features (alloc):
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(alloc_c_string)]
|
||||
#![feature(alloc_ffi)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(get_mut_unchecked)]
|
||||
#![feature(map_try_insert)]
|
||||
|
@ -11,7 +11,7 @@ use crate::thread::Result;
|
||||
|
||||
#[doc(hidden)]
|
||||
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
|
||||
#[allow_internal_unstable(libstd_sys_internals, const_format_args, core_panic)]
|
||||
#[allow_internal_unstable(libstd_sys_internals, const_format_args, core_panic, rt)]
|
||||
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
|
||||
#[rustc_macro_transparency = "semitransparent"]
|
||||
pub macro panic_2015 {
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#![crate_type = "lib"]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::const_eval_select;
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::const_eval_select;
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
<<<<<<< HEAD
|
||||
error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:29]: ~const FnOnce<()>` is not satisfied
|
||||
--> $DIR/const-eval-select-bad.rs:6:27
|
||||
|
|
||||
@ -13,6 +14,23 @@ note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select
|
||||
LL | const_eval_select((), || {}, || {});
|
||||
| ^^^^^
|
||||
= note: wrap the `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:29]` in a closure with no arguments: `|| { /* code */ }`
|
||||
=======
|
||||
error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]: ~const FnOnce<()>` is not satisfied
|
||||
--> $DIR/const-eval-select-bad.rs:7:27
|
||||
|
|
||||
LL | const_eval_select((), || {}, || {});
|
||||
| ----------------- ^^^^^ expected an `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]`
|
||||
| |
|
||||
| required by a bound introduced by this call
|
||||
|
|
||||
= help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]`
|
||||
note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]`, but that implementation is not `const`
|
||||
--> $DIR/const-eval-select-bad.rs:7:27
|
||||
|
|
||||
LL | const_eval_select((), || {}, || {});
|
||||
| ^^^^^
|
||||
= note: wrap the `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]` in a closure with no arguments: `|| { /* code */ }`
|
||||
>>>>>>> c1798b7c60e... Support unstable moves via stable in unstable items
|
||||
note: required by a bound in `const_eval_select`
|
||||
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
|
||||
|
|
||||
@ -20,7 +38,7 @@ LL | F: ~const FnOnce<ARG, Output = RET>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||
|
||||
error[E0277]: the trait bound `{integer}: ~const FnOnce<()>` is not satisfied
|
||||
--> $DIR/const-eval-select-bad.rs:8:27
|
||||
--> $DIR/const-eval-select-bad.rs:9:27
|
||||
|
|
||||
LL | const_eval_select((), 42, 0xDEADBEEF);
|
||||
| ----------------- ^^ expected an `FnOnce<()>` closure, found `{integer}`
|
||||
@ -36,7 +54,7 @@ LL | F: ~const FnOnce<ARG, Output = RET>,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||
|
||||
error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
|
||||
--> $DIR/const-eval-select-bad.rs:8:31
|
||||
--> $DIR/const-eval-select-bad.rs:9:31
|
||||
|
|
||||
LL | const_eval_select((), 42, 0xDEADBEEF);
|
||||
| ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
|
||||
@ -52,7 +70,7 @@ LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||
|
||||
error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
|
||||
--> $DIR/const-eval-select-bad.rs:28:5
|
||||
--> $DIR/const-eval-select-bad.rs:29:5
|
||||
|
|
||||
LL | const_eval_select((1,), foo, bar);
|
||||
| ^^^^^^^^^^^^^^^^^ expected `i32`, found `bool`
|
||||
@ -64,7 +82,7 @@ LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
|
||||
| ^^^^^^^^^^^^ required by this bound in `const_eval_select`
|
||||
|
||||
error[E0631]: type mismatch in function arguments
|
||||
--> $DIR/const-eval-select-bad.rs:33:32
|
||||
--> $DIR/const-eval-select-bad.rs:34:32
|
||||
|
|
||||
LL | const fn foo(n: i32) -> i32 {
|
||||
| --------------------------- found signature of `fn(i32) -> _`
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![feature(staged_api)]
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![stable(since = "1.0", feature = "ui_test")]
|
||||
|
||||
use std::intrinsics::const_eval_select;
|
||||
|
@ -1,5 +1,5 @@
|
||||
error: `const_eval_select` is not yet stable as a const fn
|
||||
--> $DIR/const-eval-select-stability.rs:16:5
|
||||
--> $DIR/const-eval-select-stability.rs:17:5
|
||||
|
|
||||
LL | const_eval_select((), nothing, log);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -2,6 +2,7 @@
|
||||
// only-x86_64
|
||||
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(core_intrinsics)]
|
||||
use std::intrinsics::const_eval_select;
|
||||
use std::arch::x86_64::*;
|
||||
use std::mem::transmute;
|
||||
|
@ -1,6 +1,7 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(const_eval_select)]
|
||||
#![feature(core_intrinsics)]
|
||||
|
||||
use std::intrinsics::const_eval_select;
|
||||
|
||||
|
@ -191,11 +191,11 @@ mod inheritance {
|
||||
stable_mod::unstable(); //~ ERROR use of unstable library feature
|
||||
stable_mod::stable();
|
||||
|
||||
unstable_mod::deprecated();
|
||||
unstable_mod::deprecated(); //~ ERROR use of unstable library feature
|
||||
unstable_mod::unstable(); //~ ERROR use of unstable library feature
|
||||
|
||||
let _ = Unstable::UnstableVariant; //~ ERROR use of unstable library feature
|
||||
let _ = Unstable::StableVariant;
|
||||
let _ = Unstable::StableVariant; //~ ERROR use of unstable library feature
|
||||
|
||||
let x: usize = 0;
|
||||
x.stable();
|
||||
|
@ -294,6 +294,14 @@ LL | stable_mod::unstable();
|
||||
|
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/lint-stability.rs:194:9
|
||||
|
|
||||
LL | unstable_mod::deprecated();
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/lint-stability.rs:195:9
|
||||
|
|
||||
@ -310,6 +318,14 @@ LL | let _ = Unstable::UnstableVariant;
|
||||
|
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/lint-stability.rs:198:17
|
||||
|
|
||||
LL | let _ = Unstable::StableVariant;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/lint-stability.rs:88:48
|
||||
|
|
||||
@ -326,6 +342,6 @@ LL | TypeUnstable = u8,
|
||||
|
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 41 previous errors
|
||||
error: aborting due to 43 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
||||
|
@ -0,0 +1,8 @@
|
||||
#![feature(staged_api)]
|
||||
#![stable(feature = "stable_test_feature", since = "1.2.0")]
|
||||
|
||||
#[unstable(feature = "unstable_test_feature", issue = "1")]
|
||||
pub mod new_unstable_module {
|
||||
#[stable(feature = "stable_test_feature", since = "1.2.0")]
|
||||
pub trait OldTrait {}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
#![feature(staged_api)]
|
||||
#![feature(unstable_test_feature)]
|
||||
#![stable(feature = "stable_test_feature", since = "1.2.0")]
|
||||
|
||||
extern crate stable_in_unstable_core;
|
||||
|
||||
#[stable(feature = "stable_test_feature", since = "1.2.0")]
|
||||
pub mod old_stable_module {
|
||||
#[stable(feature = "stable_test_feature", since = "1.2.0")]
|
||||
pub use stable_in_unstable_core::new_unstable_module::OldTrait;
|
||||
}
|
46
src/test/ui/stability-attribute/stable-in-unstable.rs
Normal file
46
src/test/ui/stability-attribute/stable-in-unstable.rs
Normal file
@ -0,0 +1,46 @@
|
||||
// This test is meant to test that we can have a stable item in an unstable module, and that
|
||||
// calling that item through the unstable module is unstable, but that re-exporting it from another
|
||||
// crate in a stable module is fine.
|
||||
//
|
||||
// This is necessary to support moving items from `std` into `core` or `alloc` unstably while still
|
||||
// exporting the original stable interface in `std`, such as moving `Error` into `core`.
|
||||
//
|
||||
// aux-build:stable-in-unstable-core.rs
|
||||
// aux-build:stable-in-unstable-std.rs
|
||||
#![crate_type = "lib"]
|
||||
|
||||
extern crate stable_in_unstable_core;
|
||||
extern crate stable_in_unstable_std;
|
||||
|
||||
mod isolated1 {
|
||||
use stable_in_unstable_core::new_unstable_module; //~ ERROR use of unstable library feature 'unstable_test_feature'
|
||||
use stable_in_unstable_core::new_unstable_module::OldTrait; //~ ERROR use of unstable library feature 'unstable_test_feature'
|
||||
}
|
||||
|
||||
mod isolated2 {
|
||||
use stable_in_unstable_std::old_stable_module::OldTrait;
|
||||
|
||||
struct LocalType;
|
||||
|
||||
impl OldTrait for LocalType {}
|
||||
}
|
||||
|
||||
mod isolated3 {
|
||||
use stable_in_unstable_core::new_unstable_module::OldTrait; //~ ERROR use of unstable library feature 'unstable_test_feature'
|
||||
|
||||
struct LocalType;
|
||||
|
||||
impl OldTrait for LocalType {}
|
||||
}
|
||||
|
||||
mod isolated4 {
|
||||
struct LocalType;
|
||||
|
||||
impl stable_in_unstable_core::new_unstable_module::OldTrait for LocalType {} //~ ERROR use of unstable library feature 'unstable_test_feature'
|
||||
}
|
||||
|
||||
mod isolated5 {
|
||||
struct LocalType;
|
||||
|
||||
impl stable_in_unstable_std::old_stable_module::OldTrait for LocalType {}
|
||||
}
|
39
src/test/ui/stability-attribute/stable-in-unstable.stderr
Normal file
39
src/test/ui/stability-attribute/stable-in-unstable.stderr
Normal file
@ -0,0 +1,39 @@
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/stable-in-unstable.rs:16:9
|
||||
|
|
||||
LL | use stable_in_unstable_core::new_unstable_module;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/stable-in-unstable.rs:17:9
|
||||
|
|
||||
LL | use stable_in_unstable_core::new_unstable_module::OldTrait;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/stable-in-unstable.rs:29:9
|
||||
|
|
||||
LL | use stable_in_unstable_core::new_unstable_module::OldTrait;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error[E0658]: use of unstable library feature 'unstable_test_feature'
|
||||
--> $DIR/stable-in-unstable.rs:39:10
|
||||
|
|
||||
LL | impl stable_in_unstable_core::new_unstable_module::OldTrait for LocalType {}
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: see issue #1 <https://github.com/rust-lang/rust/issues/1> for more information
|
||||
= help: add `#![feature(unstable_test_feature)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0658`.
|
Loading…
Reference in New Issue
Block a user