Skip to content

Commit e7fe545

Browse files
committed
Support unstable moves via stable in unstable items
1 parent 052495d commit e7fe545

File tree

20 files changed

+200
-18
lines changed

20 files changed

+200
-18
lines changed

compiler/rustc_middle/src/middle/stability.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,13 +471,15 @@ impl<'tcx> TyCtxt<'tcx> {
471471
///
472472
/// This function will also check if the item is deprecated.
473473
/// If so, and `id` is not `None`, a deprecated lint attached to `id` will be emitted.
474+
///
475+
/// Returns `true` if item is allowed aka, stable or unstable under an enabled feature.
474476
pub fn check_stability(
475477
self,
476478
def_id: DefId,
477479
id: Option<HirId>,
478480
span: Span,
479481
method_span: Option<Span>,
480-
) {
482+
) -> bool {
481483
self.check_stability_allow_unstable(def_id, id, span, method_span, AllowUnstable::No)
482484
}
483485

@@ -497,7 +499,7 @@ impl<'tcx> TyCtxt<'tcx> {
497499
span: Span,
498500
method_span: Option<Span>,
499501
allow_unstable: AllowUnstable,
500-
) {
502+
) -> bool {
501503
self.check_optional_stability(
502504
def_id,
503505
id,
@@ -516,6 +518,8 @@ impl<'tcx> TyCtxt<'tcx> {
516518
/// missing stability attributes (not necessarily just emit a `bug!`). This is necessary
517519
/// for default generic parameters, which only have stability attributes if they were
518520
/// added after the type on which they're defined.
521+
///
522+
/// Returns `true` if item is allowed aka, stable or unstable under an enabled feature.
519523
pub fn check_optional_stability(
520524
self,
521525
def_id: DefId,
@@ -524,13 +528,16 @@ impl<'tcx> TyCtxt<'tcx> {
524528
method_span: Option<Span>,
525529
allow_unstable: AllowUnstable,
526530
unmarked: impl FnOnce(Span, DefId),
527-
) {
531+
) -> bool {
528532
let soft_handler = |lint, span, msg: &_| {
529533
self.struct_span_lint_hir(lint, id.unwrap_or(hir::CRATE_HIR_ID), span, |lint| {
530534
lint.build(msg).emit();
531535
})
532536
};
533-
match self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable) {
537+
let eval_result =
538+
self.eval_stability_allow_unstable(def_id, id, span, method_span, allow_unstable);
539+
let is_allowed = matches!(eval_result, EvalResult::Allow);
540+
match eval_result {
534541
EvalResult::Allow => {}
535542
EvalResult::Deny { feature, reason, issue, suggestion, is_soft } => report_unstable(
536543
self.sess,
@@ -544,6 +551,8 @@ impl<'tcx> TyCtxt<'tcx> {
544551
),
545552
EvalResult::Unmarked => unmarked(span, def_id),
546553
}
554+
555+
is_allowed
547556
}
548557

549558
pub fn lookup_deprecation(self, id: DefId) -> Option<Deprecation> {

compiler/rustc_passes/src/stability.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
807807
fn visit_path(&mut self, path: &'tcx hir::Path<'tcx>, id: hir::HirId) {
808808
if let Some(def_id) = path.res.opt_def_id() {
809809
let method_span = path.segments.last().map(|s| s.ident.span);
810-
self.tcx.check_stability_allow_unstable(
810+
let item_is_allowed = self.tcx.check_stability_allow_unstable(
811811
def_id,
812812
Some(id),
813813
path.span,
@@ -817,8 +817,33 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
817817
} else {
818818
AllowUnstable::No
819819
},
820-
)
820+
);
821+
822+
if item_is_allowed {
823+
// Check parent modules stability as well
824+
//
825+
// We check here rather than in `visit_path_segment` to prevent visiting the last
826+
// path segment twice
827+
let parents = path.segments.iter().rev().skip(1);
828+
for path_segment in parents {
829+
if let Some(def_id) = path_segment.res.as_ref().and_then(Res::opt_def_id) {
830+
// use `None` for id to prevent deprecation check
831+
self.tcx.check_stability_allow_unstable(
832+
def_id,
833+
None,
834+
path.span,
835+
None,
836+
if is_unstable_reexport(self.tcx, id) {
837+
AllowUnstable::Yes
838+
} else {
839+
AllowUnstable::No
840+
},
841+
)
842+
}
843+
}
844+
}
821845
}
846+
822847
intravisit::walk_path(self, path)
823848
}
824849
}

compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
439439
// as the rest of the type. As such, we ignore missing
440440
// stability attributes.
441441
},
442-
)
442+
);
443443
}
444444
if let (hir::TyKind::Infer, false) = (&ty.kind, self.astconv.allow_ty_infer()) {
445445
self.inferred_params.push(ty.span);

library/core/src/intrinsics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2649,6 +2649,7 @@ pub const unsafe fn write_bytes<T>(dst: *mut T, val: u8, count: usize) {
26492649
/// Here is an example of how this could cause a problem:
26502650
/// ```no_run
26512651
/// #![feature(const_eval_select)]
2652+
/// #![feature(core_intrinsics)]
26522653
/// use std::hint::unreachable_unchecked;
26532654
/// use std::intrinsics::const_eval_select;
26542655
///

library/core/src/unicode/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
1-
#![unstable(feature = "unicode_internals", issue = "none")]
1+
#![stable(feature = "unicode_version", since = "1.45.0")]
22
#![allow(missing_docs)]
33

4+
#[unstable(feature = "unicode_internals", issue = "none")]
45
pub(crate) mod printable;
6+
#[unstable(feature = "unicode_internals", issue = "none")]
57
mod unicode_data;
68

79
/// The version of [Unicode](https://www.unicode.org/) that the Unicode parts of
@@ -18,6 +20,7 @@ mod unicode_data;
1820
pub const UNICODE_VERSION: (u8, u8, u8) = unicode_data::UNICODE_VERSION;
1921

2022
// For use in liballoc, not re-exported in libstd.
23+
#[unstable(feature = "unicode_internals", issue = "none")]
2124
pub use unicode_data::{
2225
case_ignorable::lookup as Case_Ignorable, cased::lookup as Cased, conversions,
2326
};

library/std/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@
214214
#![cfg_attr(not(bootstrap), deny(ffi_unwind_calls))]
215215
// std may use features in a platform-specific way
216216
#![allow(unused_features)]
217-
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count))]
217+
#![cfg_attr(test, feature(internal_output_capture, print_internals, update_panic_count, rt))]
218218
#![cfg_attr(
219219
all(target_vendor = "fortanix", target_env = "sgx"),
220220
feature(slice_index_methods, coerce_unsized, sgx_platform)
@@ -297,6 +297,7 @@
297297
// Library features (alloc):
298298
#![feature(alloc_layout_extra)]
299299
#![feature(alloc_c_string)]
300+
#![feature(alloc_ffi)]
300301
#![feature(allocator_api)]
301302
#![feature(get_mut_unchecked)]
302303
#![feature(map_try_insert)]

library/std/src/panic.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::thread::Result;
1111

1212
#[doc(hidden)]
1313
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
14-
#[allow_internal_unstable(libstd_sys_internals, const_format_args, core_panic)]
14+
#[allow_internal_unstable(libstd_sys_internals, const_format_args, core_panic, rt)]
1515
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
1616
#[rustc_macro_transparency = "semitransparent"]
1717
pub macro panic_2015 {

src/test/codegen/intrinsics/const_eval_select.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#![crate_type = "lib"]
44
#![feature(const_eval_select)]
5+
#![feature(core_intrinsics)]
56

67
use std::intrinsics::const_eval_select;
78

src/test/ui/intrinsics/const-eval-select-bad.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(const_eval_select)]
2+
#![feature(core_intrinsics)]
23

34
use std::intrinsics::const_eval_select;
45

src/test/ui/intrinsics/const-eval-select-bad.stderr

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
<<<<<<< HEAD
12
error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:29]: ~const FnOnce<()>` is not satisfied
23
--> $DIR/const-eval-select-bad.rs:6:27
34
|
@@ -13,14 +14,31 @@ note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select
1314
LL | const_eval_select((), || {}, || {});
1415
| ^^^^^
1516
= note: wrap the `[closure@$DIR/const-eval-select-bad.rs:6:27: 6:29]` in a closure with no arguments: `|| { /* code */ }`
17+
=======
18+
error[E0277]: the trait bound `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]: ~const FnOnce<()>` is not satisfied
19+
--> $DIR/const-eval-select-bad.rs:7:27
20+
|
21+
LL | const_eval_select((), || {}, || {});
22+
| ----------------- ^^^^^ expected an `FnOnce<()>` closure, found `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]`
23+
| |
24+
| required by a bound introduced by this call
25+
|
26+
= help: the trait `~const FnOnce<()>` is not implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]`
27+
note: the trait `FnOnce<()>` is implemented for `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]`, but that implementation is not `const`
28+
--> $DIR/const-eval-select-bad.rs:7:27
29+
|
30+
LL | const_eval_select((), || {}, || {});
31+
| ^^^^^
32+
= note: wrap the `[closure@$DIR/const-eval-select-bad.rs:7:27: 7:32]` in a closure with no arguments: `|| { /* code */ }`
33+
>>>>>>> c1798b7c60e... Support unstable moves via stable in unstable items
1634
note: required by a bound in `const_eval_select`
1735
--> $SRC_DIR/core/src/intrinsics.rs:LL:COL
1836
|
1937
LL | F: ~const FnOnce<ARG, Output = RET>,
2038
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
2139

2240
error[E0277]: the trait bound `{integer}: ~const FnOnce<()>` is not satisfied
23-
--> $DIR/const-eval-select-bad.rs:8:27
41+
--> $DIR/const-eval-select-bad.rs:9:27
2442
|
2543
LL | const_eval_select((), 42, 0xDEADBEEF);
2644
| ----------------- ^^ expected an `FnOnce<()>` closure, found `{integer}`
@@ -36,7 +54,7 @@ LL | F: ~const FnOnce<ARG, Output = RET>,
3654
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
3755

3856
error[E0277]: expected a `FnOnce<()>` closure, found `{integer}`
39-
--> $DIR/const-eval-select-bad.rs:8:31
57+
--> $DIR/const-eval-select-bad.rs:9:31
4058
|
4159
LL | const_eval_select((), 42, 0xDEADBEEF);
4260
| ----------------- ^^^^^^^^^^ expected an `FnOnce<()>` closure, found `{integer}`
@@ -52,7 +70,7 @@ LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
5270
| ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `const_eval_select`
5371

5472
error[E0271]: type mismatch resolving `<fn(i32) -> bool {bar} as FnOnce<(i32,)>>::Output == i32`
55-
--> $DIR/const-eval-select-bad.rs:28:5
73+
--> $DIR/const-eval-select-bad.rs:29:5
5674
|
5775
LL | const_eval_select((1,), foo, bar);
5876
| ^^^^^^^^^^^^^^^^^ expected `i32`, found `bool`
@@ -64,7 +82,7 @@ LL | G: FnOnce<ARG, Output = RET> + ~const Destruct,
6482
| ^^^^^^^^^^^^ required by this bound in `const_eval_select`
6583

6684
error[E0631]: type mismatch in function arguments
67-
--> $DIR/const-eval-select-bad.rs:33:32
85+
--> $DIR/const-eval-select-bad.rs:34:32
6886
|
6987
LL | const fn foo(n: i32) -> i32 {
7088
| --------------------------- found signature of `fn(i32) -> _`

0 commit comments

Comments
 (0)