mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-08 13:02:50 +00:00
Auto merge of #98375 - JohnTitor:rollup-e5c6rgo, r=JohnTitor
Rollup of 10 pull requests Successful merges: - #95446 (update CPU usage script) - #96768 (Use futex based thread parker on Fuchsia.) - #97454 (Add release notes for 1.62) - #97516 (clarify how Rust atomics correspond to C++ atomics) - #97818 (Point at return expression for RPIT-related error) - #97895 (Simplify `likely!` and `unlikely!` macro) - #98005 (Add some tests for impossible bounds) - #98226 (Document unstable `--extern` options) - #98356 (Add missing period) - #98363 (remove use of &Alloc in btree tests) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
89a0783f1c
@ -83,7 +83,7 @@ by running it with the `--help` flag or reading the [rustc dev guide][rustcguide
|
||||
If you plan to use `x.py install` to create an installation, it is recommended
|
||||
that you set the `prefix` value in the `[install]` section to a directory.
|
||||
|
||||
Create install directory if you are not installing in default directory
|
||||
Create install directory if you are not installing in default directory.
|
||||
|
||||
4. Build and install:
|
||||
|
||||
|
125
RELEASES.md
125
RELEASES.md
@ -1,3 +1,128 @@
|
||||
Version 1.62.0 (2022-06-30)
|
||||
==========================
|
||||
|
||||
Language
|
||||
--------
|
||||
|
||||
- [Stabilize `#[derive(Default)]` on enums with a `#[default]` variant][94457]
|
||||
- [Stop validating some checks in dead code after functions with uninhabited return types][93313]
|
||||
- [Fix constants not getting dropped if part of a diverging expression][94775]
|
||||
- [Support unit struct/enum variant in destructuring assignment][95380]
|
||||
- [Remove mutable_borrow_reservation_conflict lint and allow the code pattern][96268]
|
||||
|
||||
Compiler
|
||||
--------
|
||||
|
||||
- [linker: Stop using whole-archive on dependencies of dylibs][96436]
|
||||
- [Make `unaligned_references` lint deny-by-default][95372]
|
||||
This lint is also a future compatibility lint, and is expected to eventually
|
||||
become a hard error.
|
||||
- [Only add codegen backend to dep info if -Zbinary-dep-depinfo is used][93969]
|
||||
- [Reject `#[thread_local]` attribute on non-static items][95006]
|
||||
- [Add tier 3 `aarch64-pc-windows-gnullvm` and `x86_64-pc-windows-gnullvm` targets\*][94872]
|
||||
- [Implement a lint to warn about unused macro rules][96150]
|
||||
- [Promote `x86_64-unknown-none` target to Tier 2\*][95705]
|
||||
|
||||
\* Refer to Rust's [platform support page][platform-support-doc] for more
|
||||
information on Rust's tiered platform support.
|
||||
|
||||
Libraries
|
||||
---------
|
||||
|
||||
- [Move `CStr` to libcore, and `CString` to liballoc][94079]
|
||||
- [Windows: Use a pipe relay for chaining pipes][95841]
|
||||
- [Replace Linux Mutex and Condvar with futex based ones.][95035]
|
||||
- [Replace RwLock by a futex based one on Linux][95801]
|
||||
- [std: directly use pthread in UNIX parker implementation][96393]
|
||||
|
||||
Stabilized APIs
|
||||
---------------
|
||||
|
||||
- [`bool::then_some`]
|
||||
- [`f32::total_cmp`]
|
||||
- [`f64::total_cmp`]
|
||||
- [`Stdin::lines`]
|
||||
- [`windows::CommandExt::raw_arg`]
|
||||
- [`impl<T: Default> Default for AssertUnwindSafe<T>`]
|
||||
- [`From<Rc<str>> for Rc<[u8]>`][rc-u8-from-str]
|
||||
- [`From<Arc<str>> for Arc<[u8]>`][arc-u8-from-str]
|
||||
- [`FusedIterator for EncodeWide`]
|
||||
- [RDM intrinsics on aarch64][stdarch/1285]
|
||||
|
||||
Clippy
|
||||
------
|
||||
|
||||
- [Create clippy lint against unexpectedly late drop for temporaries in match scrutinee expressions][94206]
|
||||
|
||||
Cargo
|
||||
-----
|
||||
|
||||
- Added the `cargo add` command for adding dependencies to `Cargo.toml` from
|
||||
the command-line.
|
||||
[docs](https://doc.rust-lang.org/nightly/cargo/commands/cargo-add.html)
|
||||
- Package ID specs now support `name@version` syntax in addition to the
|
||||
previous `name:version` to align with the behavior in `cargo add` and other
|
||||
tools. `cargo install` and `cargo yank` also now support this syntax so the
|
||||
version does not need to passed as a separate flag.
|
||||
- The `git` and `registry` directories in Cargo's home directory (usually
|
||||
`~/.cargo`) are now marked as cache directories so that they are not
|
||||
included in backups or content indexing (on Windows).
|
||||
- Added automatic `@` argfile support, which will use "response files" if the
|
||||
command-line to `rustc` exceeds the operating system's limit.
|
||||
|
||||
Compatibility Notes
|
||||
-------------------
|
||||
|
||||
- `cargo test` now passes `--target` to `rustdoc` if the specified target is
|
||||
the same as the host target.
|
||||
[#10594](https://github.com/rust-lang/cargo/pull/10594)
|
||||
- [rustdoc: Remove .woff font files][96279]
|
||||
- [Enforce Copy bounds for repeat elements while considering lifetimes][95819]
|
||||
|
||||
Internal Changes
|
||||
----------------
|
||||
|
||||
- [Unify ReentrantMutex implementations across all platforms][96042]
|
||||
|
||||
These changes provide no direct user facing benefits, but represent significant
|
||||
improvements to the internals and overall performance of rustc
|
||||
and related tools.
|
||||
|
||||
[93313]: https://github.com/rust-lang/rust/pull/93313/
|
||||
[93969]: https://github.com/rust-lang/rust/pull/93969/
|
||||
[94079]: https://github.com/rust-lang/rust/pull/94079/
|
||||
[94206]: https://github.com/rust-lang/rust/pull/94206/
|
||||
[94457]: https://github.com/rust-lang/rust/pull/94457/
|
||||
[94775]: https://github.com/rust-lang/rust/pull/94775/
|
||||
[94872]: https://github.com/rust-lang/rust/pull/94872/
|
||||
[95006]: https://github.com/rust-lang/rust/pull/95006/
|
||||
[95035]: https://github.com/rust-lang/rust/pull/95035/
|
||||
[95372]: https://github.com/rust-lang/rust/pull/95372/
|
||||
[95380]: https://github.com/rust-lang/rust/pull/95380/
|
||||
[95431]: https://github.com/rust-lang/rust/pull/95431/
|
||||
[95705]: https://github.com/rust-lang/rust/pull/95705/
|
||||
[95801]: https://github.com/rust-lang/rust/pull/95801/
|
||||
[95819]: https://github.com/rust-lang/rust/pull/95819/
|
||||
[95841]: https://github.com/rust-lang/rust/pull/95841/
|
||||
[96042]: https://github.com/rust-lang/rust/pull/96042/
|
||||
[96150]: https://github.com/rust-lang/rust/pull/96150/
|
||||
[96268]: https://github.com/rust-lang/rust/pull/96268/
|
||||
[96279]: https://github.com/rust-lang/rust/pull/96279/
|
||||
[96393]: https://github.com/rust-lang/rust/pull/96393/
|
||||
[96436]: https://github.com/rust-lang/rust/pull/96436/
|
||||
[96557]: https://github.com/rust-lang/rust/pull/96557/
|
||||
|
||||
[`bool::then_some`]: https://doc.rust-lang.org/stable/std/primitive.bool.html#method.then_some
|
||||
[`f32::total_cmp`]: https://doc.rust-lang.org/stable/std/primitive.f32.html#method.total_cmp
|
||||
[`f64::total_cmp`]: https://doc.rust-lang.org/stable/std/primitive.f64.html#method.total_cmp
|
||||
[`Stdin::lines`]: https://doc.rust-lang.org/stable/std/io/struct.Stdin.html#method.lines
|
||||
[`impl<T: Default> Default for AssertUnwindSafe<T>`]: https://doc.rust-lang.org/stable/std/panic/struct.AssertUnwindSafe.html#impl-Default
|
||||
[rc-u8-from-str]: https://doc.rust-lang.org/stable/std/rc/struct.Rc.html#impl-From%3CRc%3Cstr%3E%3E
|
||||
[arc-u8-from-str]: https://doc.rust-lang.org/stable/std/sync/struct.Arc.html#impl-From%3CArc%3Cstr%3E%3E
|
||||
[stdarch/1285]: https://github.com/rust-lang/stdarch/pull/1285
|
||||
[`windows::CommandExt::raw_arg`]: https://doc.rust-lang.org/stable/std/os/windows/process/trait.CommandExt.html#tymethod.raw_arg
|
||||
[`FusedIterator for EncodeWide`]: https://doc.rust-lang.org/stable/std/os/windows/ffi/struct.EncodeWide.html#impl-FusedIterator
|
||||
|
||||
Version 1.61.0 (2022-05-19)
|
||||
==========================
|
||||
|
||||
|
@ -11,7 +11,6 @@
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(auto_traits)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(extend_one)]
|
||||
#![feature(let_else)]
|
||||
#![feature(hash_raw_entry)]
|
||||
@ -44,26 +43,6 @@ pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
|
||||
f()
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! likely {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
#[allow(unused_unsafe)]
|
||||
e => unsafe { std::intrinsics::likely(e) },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unlikely {
|
||||
($e:expr) => {
|
||||
match $e {
|
||||
#[allow(unused_unsafe)]
|
||||
e => unsafe { std::intrinsics::unlikely(e) },
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub mod base_n;
|
||||
pub mod binary_search_util;
|
||||
pub mod captures;
|
||||
|
@ -195,6 +195,7 @@ impl SelfProfilerRef {
|
||||
F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>,
|
||||
{
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
fn cold_call<F>(profiler_ref: &SelfProfilerRef, f: F) -> TimingGuard<'_>
|
||||
where
|
||||
F: for<'a> FnOnce(&'a SelfProfiler) -> TimingGuard<'a>,
|
||||
@ -203,7 +204,7 @@ impl SelfProfilerRef {
|
||||
f(&**profiler)
|
||||
}
|
||||
|
||||
if unlikely!(self.event_filter_mask.contains(event_filter)) {
|
||||
if self.event_filter_mask.contains(event_filter) {
|
||||
cold_call(self, f)
|
||||
} else {
|
||||
TimingGuard::none()
|
||||
|
@ -5,7 +5,7 @@ use hir::{HirId, OpaqueTyOrigin};
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_data_structures::vec_map::VecMap;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
|
||||
use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::subst::{GenericArgKind, Subst};
|
||||
use rustc_middle::ty::{
|
||||
@ -46,6 +46,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
value: T,
|
||||
body_id: HirId,
|
||||
span: Span,
|
||||
code: ObligationCauseCode<'tcx>,
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> InferOk<'tcx, T> {
|
||||
if !value.has_opaque_types() {
|
||||
@ -68,10 +69,13 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
) =>
|
||||
{
|
||||
let span = if span.is_dummy() { self.tcx.def_span(def_id) } else { span };
|
||||
let cause = ObligationCause::misc(span, body_id);
|
||||
let cause = ObligationCause::new(span, body_id, code.clone());
|
||||
// FIXME(compiler-errors): We probably should add a new TypeVariableOriginKind
|
||||
// for opaque types, and then use that kind to fix the spans for type errors
|
||||
// that we see later on.
|
||||
let ty_var = self.next_ty_var(TypeVariableOrigin {
|
||||
kind: TypeVariableOriginKind::TypeInference,
|
||||
span: cause.span,
|
||||
span,
|
||||
});
|
||||
obligations.extend(
|
||||
self.handle_opaque_type(ty, ty_var, true, &cause, param_env)
|
||||
|
@ -387,6 +387,9 @@ pub enum ObligationCauseCode<'tcx> {
|
||||
/// Return type of this function
|
||||
ReturnType,
|
||||
|
||||
/// Opaque return type of this function
|
||||
OpaqueReturnType(Option<(Ty<'tcx>, Span)>),
|
||||
|
||||
/// Block implicit return
|
||||
BlockTailExpression(hir::HirId),
|
||||
|
||||
|
@ -804,7 +804,7 @@ pub type PolyTraitPredicate<'tcx> = ty::Binder<'tcx, TraitPredicate<'tcx>>;
|
||||
|
||||
impl<'tcx> TraitPredicate<'tcx> {
|
||||
pub fn remap_constness(&mut self, tcx: TyCtxt<'tcx>, param_env: &mut ParamEnv<'tcx>) {
|
||||
if unlikely!(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) {
|
||||
if std::intrinsics::unlikely(Some(self.trait_ref.def_id) == tcx.lang_items().drop_trait()) {
|
||||
// remap without changing constness of this predicate.
|
||||
// this is because `T: ~const Drop` has a different meaning to `T: Drop`
|
||||
// FIXME(fee1-dead): remove this logic after beta bump
|
||||
|
@ -750,7 +750,7 @@ impl<K: DepKind> DepGraph<K> {
|
||||
dep_node
|
||||
);
|
||||
|
||||
if unlikely!(!side_effects.is_empty()) {
|
||||
if !side_effects.is_empty() {
|
||||
self.emit_side_effects(tcx, data, dep_node_index, side_effects);
|
||||
}
|
||||
|
||||
|
@ -316,7 +316,7 @@ where
|
||||
OnHit: FnOnce(&C::Stored) -> R,
|
||||
{
|
||||
cache.lookup(&key, |value, index| {
|
||||
if unlikely!(tcx.profiler().enabled()) {
|
||||
if std::intrinsics::unlikely(tcx.profiler().enabled()) {
|
||||
tcx.profiler().query_cache_hit(index.into());
|
||||
}
|
||||
tcx.dep_graph().read_index(index);
|
||||
@ -354,7 +354,7 @@ where
|
||||
.lookup(&key, |value, index| (value.clone(), index))
|
||||
.unwrap_or_else(|_| panic!("value must be in cache after waiting"));
|
||||
|
||||
if unlikely!(tcx.dep_context().profiler().enabled()) {
|
||||
if std::intrinsics::unlikely(tcx.dep_context().profiler().enabled()) {
|
||||
tcx.dep_context().profiler().query_cache_hit(index.into());
|
||||
}
|
||||
query_blocked_prof_timer.finish_with_query_invocation_id(index.into());
|
||||
@ -422,7 +422,7 @@ where
|
||||
let diagnostics = diagnostics.into_inner();
|
||||
let side_effects = QuerySideEffects { diagnostics };
|
||||
|
||||
if unlikely!(!side_effects.is_empty()) {
|
||||
if std::intrinsics::unlikely(!side_effects.is_empty()) {
|
||||
if query.anon {
|
||||
tcx.store_side_effects_for_anon_node(dep_node_index, side_effects);
|
||||
} else {
|
||||
@ -466,7 +466,9 @@ where
|
||||
prof_timer.finish_with_query_invocation_id(dep_node_index.into());
|
||||
|
||||
if let Some(result) = result {
|
||||
if unlikely!(tcx.dep_context().sess().opts.debugging_opts.query_dep_graph) {
|
||||
if std::intrinsics::unlikely(
|
||||
tcx.dep_context().sess().opts.debugging_opts.query_dep_graph,
|
||||
) {
|
||||
dep_graph.mark_debug_loaded_from_disk(*dep_node)
|
||||
}
|
||||
|
||||
@ -483,8 +485,8 @@ where
|
||||
// currently afford to verify every hash. This subset should still
|
||||
// give us some coverage of potential bugs though.
|
||||
let try_verify = prev_fingerprint.as_value().1 % 32 == 0;
|
||||
if unlikely!(
|
||||
try_verify || tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich
|
||||
if std::intrinsics::unlikely(
|
||||
try_verify || tcx.dep_context().sess().opts.debugging_opts.incremental_verify_ich,
|
||||
) {
|
||||
incremental_verify_ich(*tcx.dep_context(), &result, dep_node, query);
|
||||
}
|
||||
@ -723,7 +725,7 @@ where
|
||||
// Ensure that only one of them runs the query.
|
||||
let cache = Q::query_cache(tcx);
|
||||
let cached = cache.lookup(&key, |_, index| {
|
||||
if unlikely!(tcx.dep_context().profiler().enabled()) {
|
||||
if std::intrinsics::unlikely(tcx.dep_context().profiler().enabled()) {
|
||||
tcx.dep_context().profiler().query_cache_hit(index.into());
|
||||
}
|
||||
});
|
||||
|
@ -2661,6 +2661,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
|
||||
err.help("add `#![feature(trivial_bounds)]` to the crate attributes to enable");
|
||||
}
|
||||
}
|
||||
ObligationCauseCode::OpaqueReturnType(expr_info) => {
|
||||
if let Some((expr_ty, expr_span)) = expr_info {
|
||||
let expr_ty = self.resolve_vars_if_possible(expr_ty);
|
||||
err.span_label(
|
||||
expr_span,
|
||||
format!("return type was inferred to be `{expr_ty}` here"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ use rustc_hir::def::DefKind;
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::infer::resolve::OpportunisticRegionResolver;
|
||||
use rustc_infer::traits::ObligationCauseCode;
|
||||
use rustc_middle::traits::select::OverflowError;
|
||||
use rustc_middle::ty::fold::{MaxUniverse, TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
use rustc_middle::ty::subst::Subst;
|
||||
@ -261,6 +262,7 @@ fn project_and_unify_type<'cx, 'tcx>(
|
||||
actual,
|
||||
obligation.cause.body_id,
|
||||
obligation.cause.span,
|
||||
ObligationCauseCode::MiscObligation,
|
||||
obligation.param_env,
|
||||
);
|
||||
obligations.extend(new);
|
||||
|
@ -101,8 +101,13 @@ pub(super) fn check_fn<'a, 'tcx>(
|
||||
declared_ret_ty,
|
||||
body.value.hir_id,
|
||||
DUMMY_SP,
|
||||
traits::ObligationCauseCode::OpaqueReturnType(None),
|
||||
param_env,
|
||||
));
|
||||
// If we replaced declared_ret_ty with infer vars, then we must be infering
|
||||
// an opaque type, so set a flag so we can improve diagnostics.
|
||||
fcx.return_type_has_opaque = ret_ty != declared_ret_ty;
|
||||
|
||||
fcx.ret_coercion = Some(RefCell::new(CoerceMany::new(ret_ty)));
|
||||
fcx.ret_type_span = Some(decl.output.span());
|
||||
|
||||
|
@ -10,6 +10,7 @@ use rustc_hir::lang_items::LangItem;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||
use rustc_infer::infer::{InferOk, InferResult};
|
||||
use rustc_infer::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::fold::TypeFoldable;
|
||||
use rustc_middle::ty::subst::InternalSubsts;
|
||||
use rustc_middle::ty::{self, Ty};
|
||||
@ -645,8 +646,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn hide_parent_opaque_types(&self, ty: Ty<'tcx>, span: Span, body_id: hir::HirId) -> Ty<'tcx> {
|
||||
let InferOk { value, obligations } =
|
||||
self.replace_opaque_types_with_inference_vars(ty, body_id, span, self.param_env);
|
||||
let InferOk { value, obligations } = self.replace_opaque_types_with_inference_vars(
|
||||
ty,
|
||||
body_id,
|
||||
span,
|
||||
ObligationCauseCode::MiscObligation,
|
||||
self.param_env,
|
||||
);
|
||||
self.register_predicates(obligations);
|
||||
value
|
||||
}
|
||||
|
@ -39,6 +39,7 @@ use rustc_hir::{ExprKind, HirId, QPath};
|
||||
use rustc_infer::infer;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
use rustc_infer::infer::InferOk;
|
||||
use rustc_infer::traits::ObligationCause;
|
||||
use rustc_middle::middle::stability;
|
||||
use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
|
||||
use rustc_middle::ty::error::TypeError::FieldMisMatch;
|
||||
@ -839,6 +840,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
return_expr,
|
||||
return_expr_ty,
|
||||
);
|
||||
|
||||
if self.return_type_has_opaque {
|
||||
// Point any obligations that were registered due to opaque type
|
||||
// inference at the return expression.
|
||||
self.select_obligations_where_possible(false, |errors| {
|
||||
self.point_at_return_for_opaque_ty_error(errors, span, return_expr_ty);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn point_at_return_for_opaque_ty_error(
|
||||
&self,
|
||||
errors: &mut Vec<traits::FulfillmentError<'tcx>>,
|
||||
span: Span,
|
||||
return_expr_ty: Ty<'tcx>,
|
||||
) {
|
||||
// Don't point at the whole block if it's empty
|
||||
if span == self.tcx.hir().span(self.body_id) {
|
||||
return;
|
||||
}
|
||||
for err in errors {
|
||||
let cause = &mut err.obligation.cause;
|
||||
if let ObligationCauseCode::OpaqueReturnType(None) = cause.code() {
|
||||
let new_cause = ObligationCause::new(
|
||||
cause.span,
|
||||
cause.body_id,
|
||||
ObligationCauseCode::OpaqueReturnType(Some((return_expr_ty, span))),
|
||||
);
|
||||
*cause = new_cause;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn check_lhs_assignable(
|
||||
|
@ -115,6 +115,9 @@ pub struct FnCtxt<'a, 'tcx> {
|
||||
/// either given explicitly or inferred from, say, an `Fn*` trait
|
||||
/// bound. Used for diagnostic purposes only.
|
||||
pub(super) return_type_pre_known: bool,
|
||||
|
||||
/// True if the return type has an Opaque type
|
||||
pub(super) return_type_has_opaque: bool,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@ -141,6 +144,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}),
|
||||
inh,
|
||||
return_type_pre_known: true,
|
||||
return_type_has_opaque: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,10 +68,10 @@ fn test_splitpoint() {
|
||||
|
||||
#[test]
|
||||
fn test_partial_eq() {
|
||||
let mut root1 = NodeRef::new_leaf(&Global);
|
||||
let mut root1 = NodeRef::new_leaf(Global);
|
||||
root1.borrow_mut().push(1, ());
|
||||
let mut root1 = NodeRef::new_internal(root1.forget_type(), &Global).forget_type();
|
||||
let root2 = Root::new(&Global);
|
||||
let mut root1 = NodeRef::new_internal(root1.forget_type(), Global).forget_type();
|
||||
let root2 = Root::new(Global);
|
||||
root1.reborrow().assert_back_pointers();
|
||||
root2.reborrow().assert_back_pointers();
|
||||
|
||||
@ -87,9 +87,9 @@ fn test_partial_eq() {
|
||||
assert!(top_edge_1 == top_edge_1);
|
||||
assert!(top_edge_1 != top_edge_2);
|
||||
|
||||
root1.pop_internal_level(&Global);
|
||||
unsafe { root1.into_dying().deallocate_and_ascend(&Global) };
|
||||
unsafe { root2.into_dying().deallocate_and_ascend(&Global) };
|
||||
root1.pop_internal_level(Global);
|
||||
unsafe { root1.into_dying().deallocate_and_ascend(Global) };
|
||||
unsafe { root2.into_dying().deallocate_and_ascend(Global) };
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -4,6 +4,12 @@
|
||||
//! threads, and are the building blocks of other concurrent
|
||||
//! types.
|
||||
//!
|
||||
//! Rust atomics currently follow the same rules as [C++20 atomics][cpp], specifically `atomic_ref`.
|
||||
//! Basically, creating a *shared reference* to one of the Rust atomic types corresponds to creating
|
||||
//! an `atomic_ref` in C++; the `atomic_ref` is destroyed when the lifetime of the shared reference
|
||||
//! ends. (A Rust atomic type that is exclusively owned or behind a mutable reference does *not*
|
||||
//! correspond to an "atomic object" in C++, since it can be accessed via non-atomic operations.)
|
||||
//!
|
||||
//! This module defines atomic versions of a select number of primitive
|
||||
//! types, including [`AtomicBool`], [`AtomicIsize`], [`AtomicUsize`],
|
||||
//! [`AtomicI8`], [`AtomicU16`], etc.
|
||||
@ -14,6 +20,7 @@
|
||||
//! the memory barrier for that operation. These orderings are the
|
||||
//! same as the [C++20 atomic orderings][1]. For more information see the [nomicon][2].
|
||||
//!
|
||||
//! [cpp]: https://en.cppreference.com/w/cpp/atomic
|
||||
//! [1]: https://en.cppreference.com/w/cpp/atomic/memory_order
|
||||
//! [2]: ../../../nomicon/atomics.html
|
||||
//!
|
||||
|
@ -5,6 +5,7 @@
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "fuchsia",
|
||||
))]
|
||||
|
||||
use crate::sync::atomic::AtomicU32;
|
||||
@ -237,3 +238,52 @@ pub fn futex_wake(futex: &AtomicU32) -> bool {
|
||||
pub fn futex_wake_all(futex: &AtomicU32) {
|
||||
unsafe { emscripten_futex_wake(futex, i32::MAX) };
|
||||
}
|
||||
|
||||
#[cfg(target_os = "fuchsia")]
|
||||
mod zircon {
|
||||
type zx_time_t = i64;
|
||||
type zx_futex_t = crate::sync::atomic::AtomicU32;
|
||||
type zx_handle_t = u32;
|
||||
type zx_status_t = i32;
|
||||
|
||||
pub const ZX_HANDLE_INVALID: zx_handle_t = 0;
|
||||
pub const ZX_ERR_TIMED_OUT: zx_status_t = -21;
|
||||
pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX;
|
||||
|
||||
extern "C" {
|
||||
pub fn zx_futex_wait(
|
||||
value_ptr: *const zx_futex_t,
|
||||
current_value: zx_futex_t,
|
||||
new_futex_owner: zx_handle_t,
|
||||
deadline: zx_time_t,
|
||||
) -> zx_status_t;
|
||||
pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t;
|
||||
pub fn zx_clock_get_monotonic() -> zx_time_t;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(target_os = "fuchsia")]
|
||||
pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -> bool {
|
||||
use crate::convert::TryFrom;
|
||||
|
||||
// Sleep forever if the timeout is longer than fits in a i64.
|
||||
let deadline = timeout
|
||||
.and_then(|d| {
|
||||
i64::try_from(d.as_nanos())
|
||||
.ok()?
|
||||
.checked_add(unsafe { zircon::zx_clock_get_monotonic() })
|
||||
})
|
||||
.unwrap_or(zircon::ZX_TIME_INFINITE);
|
||||
|
||||
unsafe {
|
||||
zircon::zx_futex_wait(futex, AtomicU32::new(expected), zircon::ZX_HANDLE_INVALID, deadline)
|
||||
!= zircon::ZX_ERR_TIMED_OUT
|
||||
}
|
||||
}
|
||||
|
||||
// Fuchsia doesn't tell us how many threads are woken up, so this always returns false.
|
||||
#[cfg(target_os = "fuchsia")]
|
||||
pub fn futex_wake(futex: &AtomicU32) -> bool {
|
||||
unsafe { zircon::zx_futex_wake(futex, 1) };
|
||||
false
|
||||
}
|
||||
|
@ -7,6 +7,7 @@
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "fuchsia",
|
||||
)))]
|
||||
|
||||
use crate::cell::UnsafeCell;
|
||||
|
@ -6,6 +6,7 @@ cfg_if::cfg_if! {
|
||||
target_os = "freebsd",
|
||||
target_os = "openbsd",
|
||||
target_os = "dragonfly",
|
||||
target_os = "fuchsia",
|
||||
))] {
|
||||
mod futex;
|
||||
pub use futex::Parker;
|
||||
|
22
src/doc/unstable-book/src/compiler-flags/extern-options.md
Normal file
22
src/doc/unstable-book/src/compiler-flags/extern-options.md
Normal file
@ -0,0 +1,22 @@
|
||||
# `--extern` Options
|
||||
|
||||
The behavior of the `--extern` flag can be modified with `noprelude`, `priv` or `nounused` options.
|
||||
|
||||
This is unstable feature, so you have to provide `-Zunstable-options` to enable it.
|
||||
|
||||
## Examples
|
||||
|
||||
Use your own build of the `core` crate.
|
||||
|
||||
`rustc main.rs -Z unstable-options --extern noprelude:core=libcore.rlib`
|
||||
|
||||
To use multiple options, separate them with a comma:
|
||||
|
||||
`rustc main.rs -Z unstable-options --extern noprelude,priv,nounused:mydep=mydep.rlib`
|
||||
|
||||
## Options
|
||||
|
||||
* `noprelude`: Do not add the crate to the external prelude. If used, it will need to be imported using `extern crate`.
|
||||
This is used by the [build-std project](https://github.com/rust-lang/wg-cargo-std-aware/) to simulate compatibility with sysroot-only crates.
|
||||
* `priv`: Mark the crate as a private dependency for the [`exported_private_dependencies`](../../rustc/lints/listing/warn-by-default.html#exported-private-dependencies) lint.
|
||||
* `nounused`: Suppress [`unused-crate-dependencies`](../../rustc/lints/listing/allowed-by-default.html#unused-crate-dependencies) warnings for the crate.
|
@ -7,13 +7,21 @@
|
||||
# commit SHA of the build you're interested in, and the second is the name of
|
||||
# the builder. For example:
|
||||
#
|
||||
# ./src/etc/cpu-usage-over-time-plot.sh e699ea096fcc2fc9ce8e8bcf884e11496a31cc9f i686-mingw-1
|
||||
# ./src/etc/cpu-usage-over-time-plot.sh 7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c x86_64-gnu
|
||||
#
|
||||
# That will generate `$builder.png` in the current directory which you can open
|
||||
# up to see a hopefully pretty graph.
|
||||
#
|
||||
# Improvements to this script are greatly appreciated!
|
||||
|
||||
if [[ $# != 2 ]]; then
|
||||
echo "expected 2 arguments, recieved $#"
|
||||
echo "example usage: './src/etc/cpu-usage-over-time-plot.sh \
|
||||
7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c \
|
||||
x86_64-gnu'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -ex
|
||||
|
||||
bucket=rust-lang-ci2
|
||||
@ -30,7 +38,7 @@ set ylabel "CPU Usage %"
|
||||
set xlabel "Time"
|
||||
set datafile sep ','
|
||||
set term png size 3000,1000
|
||||
set output "$builder.png"
|
||||
set output "$builder-$commit-cpu-usage-plot.png"
|
||||
set grid
|
||||
|
||||
f(x) = mean_y
|
||||
@ -43,7 +51,9 @@ set ytics 10
|
||||
set boxwidth 0.5
|
||||
|
||||
plot \\
|
||||
mean_y with lines linetype 1 linecolor rgb "#ff0000" title "average", \\
|
||||
"cpu-$builder.csv" using 1:(100-\$2) with points pointtype 7 pointsize 0.4 title "$builder", \\
|
||||
"" using 1:(100-\$2) smooth bezier linewidth 3 title "bezier"
|
||||
mean_y with lines linetype 1 linecolor rgb "#ff0000" title "average", "cpu-$builder.csv" \\
|
||||
using 1:(100-\$2) with points pointtype 7 pointsize 0.4 title "$builder", "" \\
|
||||
using 1:(100-\$2) smooth bezier linewidth 3 title "bezier"
|
||||
EOF
|
||||
|
||||
rm "cpu-$builder.csv"
|
||||
|
@ -6,6 +6,9 @@ LL | fn bar() -> impl Bar {
|
||||
...
|
||||
LL | fn baz() -> impl Bar<Item = i32> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^ expected associated type, found `i32`
|
||||
LL |
|
||||
LL | bar()
|
||||
| ----- return type was inferred to be `impl Bar` here
|
||||
|
|
||||
= note: expected associated type `<impl Bar as Foo>::Item`
|
||||
found type `i32`
|
||||
|
@ -3,6 +3,9 @@ error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied
|
||||
|
|
||||
LL | fn rawr() -> impl Trait {
|
||||
| ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>`
|
||||
LL |
|
||||
LL | Uwu::<10, 12>
|
||||
| ------------- return type was inferred to be `Uwu<10_u32, 12_u32>` here
|
||||
|
|
||||
= help: the trait `Trait` is implemented for `Uwu<N>`
|
||||
|
||||
@ -11,6 +14,9 @@ error[E0277]: the trait bound `u32: Traitor<N>` is not satisfied
|
||||
|
|
||||
LL | fn uwu<const N: u8>() -> impl Traitor<N> {
|
||||
| ^^^^^^^^^^^^^^^ the trait `Traitor<N>` is not implemented for `u32`
|
||||
LL |
|
||||
LL | 1_u32
|
||||
| ----- return type was inferred to be `u32` here
|
||||
|
|
||||
= help: the following other types implement trait `Traitor<N, M>`:
|
||||
<u32 as Traitor<N, 2_u8>>
|
||||
@ -21,6 +27,9 @@ error[E0277]: the trait bound `u64: Traitor` is not satisfied
|
||||
|
|
||||
LL | fn owo() -> impl Traitor {
|
||||
| ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64`
|
||||
LL |
|
||||
LL | 1_u64
|
||||
| ----- return type was inferred to be `u64` here
|
||||
|
|
||||
= help: the following other types implement trait `Traitor<N, M>`:
|
||||
<u32 as Traitor<N, 2_u8>>
|
||||
|
@ -3,6 +3,9 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as imp
|
||||
|
|
||||
LL | fn foo_fail<T: Trait>() -> impl FooLike<Output = T::Assoc> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as impl_trait::Trait>::Assoc`
|
||||
LL |
|
||||
LL | Foo(())
|
||||
| ------- return type was inferred to be `Foo<()>` here
|
||||
|
|
||||
note: expected this to be `()`
|
||||
--> $DIR/bound-normalization-fail.rs:14:19
|
||||
@ -27,6 +30,9 @@ error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lif
|
||||
|
|
||||
LL | fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as lifetimes::Trait<'static>>::Assoc`
|
||||
...
|
||||
LL | Foo(())
|
||||
| ------- return type was inferred to be `Foo<()>` here
|
||||
|
|
||||
note: expected this to be `()`
|
||||
--> $DIR/bound-normalization-fail.rs:14:19
|
||||
|
@ -9,6 +9,9 @@ error[E0277]: `u32` is not a future
|
||||
|
|
||||
LL | fn test_ref(x: &u32) -> impl std::future::Future<Output = u32> + '_ {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `u32` is not a future
|
||||
LL |
|
||||
LL | *x
|
||||
| -- return type was inferred to be `u32` here
|
||||
|
|
||||
= help: the trait `Future` is not implemented for `u32`
|
||||
= note: u32 must be a future or must implement `IntoFuture` to be awaited
|
||||
|
@ -1,10 +1,15 @@
|
||||
// compile-flags: -Zmir-opt-level=4
|
||||
// build-pass
|
||||
// compile-flags: -Zmir-opt-level=3 --crate-type=lib
|
||||
|
||||
pub fn bar<T>(s: &'static mut ())
|
||||
where
|
||||
&'static mut (): Clone, //~ ERROR the trait bound
|
||||
{
|
||||
<&'static mut () as Clone>::clone(&s);
|
||||
#![feature(trivial_bounds)]
|
||||
#![allow(trivial_bounds)]
|
||||
|
||||
trait Foo {
|
||||
fn test(self);
|
||||
}
|
||||
fn baz<T>()
|
||||
where
|
||||
&'static str: Foo,
|
||||
{
|
||||
"Foo".test()
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,12 +0,0 @@
|
||||
error[E0277]: the trait bound `&'static mut (): Clone` is not satisfied
|
||||
--> $DIR/issue-93008.rs:5:5
|
||||
|
|
||||
LL | &'static mut (): Clone,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^ the trait `Clone` is not implemented for `&'static mut ()`
|
||||
|
|
||||
= help: see issue #48214
|
||||
= help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
14
src/test/ui/trait-bounds/issue-94680.rs
Normal file
14
src/test/ui/trait-bounds/issue-94680.rs
Normal file
@ -0,0 +1,14 @@
|
||||
// check-pass
|
||||
|
||||
fn main() {
|
||||
println!("{:?}", {
|
||||
type T = ();
|
||||
|
||||
pub fn cloneit(it: &'_ mut T) -> (&'_ mut T, &'_ mut T)
|
||||
where
|
||||
for<'any> &'any mut T: Clone,
|
||||
{
|
||||
(it.clone(), it)
|
||||
}
|
||||
});
|
||||
}
|
34
src/test/ui/trait-bounds/issue-94999.rs
Normal file
34
src/test/ui/trait-bounds/issue-94999.rs
Normal file
@ -0,0 +1,34 @@
|
||||
// check-pass
|
||||
|
||||
trait Identity<Q> {
|
||||
type T;
|
||||
}
|
||||
|
||||
impl<Q, T> Identity<Q> for T {
|
||||
type T = T;
|
||||
}
|
||||
|
||||
trait Holds {
|
||||
type Q;
|
||||
}
|
||||
|
||||
struct S;
|
||||
struct X(S);
|
||||
|
||||
struct XHelper;
|
||||
|
||||
impl Holds for X {
|
||||
type Q = XHelper;
|
||||
}
|
||||
|
||||
impl<Q> Clone for X
|
||||
where
|
||||
<S as Identity<Q>>::T: Clone,
|
||||
X: Holds<Q = Q>,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
31
src/test/ui/trait-bounds/issue-95640.rs
Normal file
31
src/test/ui/trait-bounds/issue-95640.rs
Normal file
@ -0,0 +1,31 @@
|
||||
// build-pass
|
||||
// compile-flags:-Zmir-opt-level=3
|
||||
|
||||
struct D;
|
||||
|
||||
trait Tr {
|
||||
type It;
|
||||
fn foo(self) -> Option<Self::It>;
|
||||
}
|
||||
|
||||
impl<'a> Tr for &'a D {
|
||||
type It = ();
|
||||
fn foo(self) -> Option<()> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn run<F>(f: F)
|
||||
where
|
||||
for<'a> &'a D: Tr,
|
||||
F: Fn(<&D as Tr>::It),
|
||||
{
|
||||
let d = &D;
|
||||
while let Some(i) = d.foo() {
|
||||
f(i);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
run(|_| {});
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
// known-bug
|
||||
// build-fail
|
||||
// failure-status: 101
|
||||
// compile-flags:--crate-type=lib -Zmir-opt-level=3
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
|
||||
// normalize-stderr-test "thread 'rustc' panicked.*" -> "thread 'rustc' panicked"
|
||||
// normalize-stderr-test "note:.*RUST_BACKTRACE=1.*\n" -> ""
|
||||
// normalize-stderr-test "error: internal compiler error.*" -> "error: internal compiler error"
|
||||
// normalize-stderr-test "encountered.*with incompatible types:" "encountered ... with incompatible types:"
|
||||
// normalize-stderr-test "note:.*unexpectedly panicked.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: we would appreciate a bug report.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: compiler flags.*\n\n" -> ""
|
||||
// normalize-stderr-test "note: rustc.*running on.*\n\n" -> ""
|
||||
// normalize-stderr-test "query stack during panic:\n" -> ""
|
||||
// normalize-stderr-test "we're just showing a limited slice of the query stack\n" -> ""
|
||||
// normalize-stderr-test "end of query stack\n" -> ""
|
||||
// normalize-stderr-test "#.*\n" -> ""
|
||||
|
||||
// This is a known bug that @compiler-errors tried to fix in #94238,
|
||||
// but the solution was probably not correct.
|
||||
|
||||
pub trait Factory<T> {
|
||||
type Item;
|
||||
}
|
||||
|
||||
pub struct IntFactory;
|
||||
|
||||
impl<T> Factory<T> for IntFactory {
|
||||
type Item = usize;
|
||||
}
|
||||
|
||||
pub fn foo<T>()
|
||||
where
|
||||
IntFactory: Factory<T>,
|
||||
{
|
||||
let mut x: <IntFactory as Factory<T>>::Item = bar::<T>();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bar<T>() -> <IntFactory as Factory<T>>::Item {
|
||||
0usize
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
error: internal compiler error
|
||||
|
||||
error: internal compiler error
|
||||
encountered ... with incompatible types:
|
||||
left-hand side has type: <IntFactory as Factory<T>>::Item
|
||||
right-hand side has type: usize
|
||||
--> $DIR/select-param-env-instead-of-blanket.rs:42:5
|
||||
|
|
||||
LL | let mut x: <IntFactory as Factory<T>>::Item = bar::<T>();
|
||||
| ---------- in this inlined function call
|
||||
...
|
||||
LL | 0usize
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: delayed at compiler/rustc_const_eval/src/transform/validate.rs:128:36
|
||||
|
||||
thread 'rustc' panicked
|
||||
|
@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
|
||||
|
|
||||
LL | fn foo() -> impl Foo<FooX> {
|
||||
| ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
|
||||
...
|
||||
LL | ()
|
||||
| -- return type was inferred to be `()` here
|
||||
|
|
||||
= help: the trait `Foo<()>` is implemented for `()`
|
||||
|
||||
|
@ -3,6 +3,9 @@ error[E0277]: the trait bound `(): Foo<FooX>` is not satisfied
|
||||
|
|
||||
LL | fn foo() -> impl Foo<FooX> {
|
||||
| ^^^^^^^^^^^^^^ the trait `Foo<FooX>` is not implemented for `()`
|
||||
LL |
|
||||
LL | ()
|
||||
| -- return type was inferred to be `()` here
|
||||
|
|
||||
= help: the following other types implement trait `Foo<A>`:
|
||||
<() as Foo<()>>
|
||||
|
Loading…
Reference in New Issue
Block a user