Support unstable moves via stable in unstable items

This commit is contained in:
Jane Lusby 2022-04-11 18:12:26 -07:00 committed by Jane Losare-Lusby
parent 052495d001
commit e7fe5456c5
20 changed files with 200 additions and 18 deletions

View File

@ -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> {

View File

@ -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)
}
}

View File

@ -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);

View File

@ -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;
///

View File

@ -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,
};

View File

@ -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)]

View File

@ -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 {

View File

@ -2,6 +2,7 @@
#![crate_type = "lib"]
#![feature(const_eval_select)]
#![feature(core_intrinsics)]
use std::intrinsics::const_eval_select;

View File

@ -1,4 +1,5 @@
#![feature(const_eval_select)]
#![feature(core_intrinsics)]
use std::intrinsics::const_eval_select;

View File

@ -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) -> _`

View File

@ -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;

View File

@ -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);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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;

View File

@ -1,6 +1,7 @@
// run-pass
#![feature(const_eval_select)]
#![feature(core_intrinsics)]
use std::intrinsics::const_eval_select;

View File

@ -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();

View File

@ -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`.

View File

@ -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 {}
}

View File

@ -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;
}

View 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 {}
}

View 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`.