mirror of
https://github.com/openharmony/third_party_rust_rust.git
synced 2026-07-19 19:53:38 -04:00
Auto merge of #103322 - matthiaskrgr:rollup-m9zgpft, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #103221 (Fix `SelfVisitor::is_self_ty` ICE) - #103230 (Clarify startup) - #103281 (Adjust `transmute{,_copy}` to be clearer about which of `T` and `U` is input vs output) - #103288 (Fixed docs typo in `library/std/src/time.rs`) - #103296 (+/- shortcut now only expand/collapse, not both) - #103297 (fix typo) - #103313 (Don't label `src/test` tests as `A-testsuite`) - #103315 (interpret: remove an incorrect assertion) - #103319 (Improve "`~const` is not allowed here" message) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -38,6 +38,13 @@ enum SelfSemantic {
|
||||
No,
|
||||
}
|
||||
|
||||
/// What is the context that prevents using `~const`?
|
||||
enum DisallowTildeConstContext<'a> {
|
||||
TraitObject,
|
||||
ImplTrait,
|
||||
Fn(FnKind<'a>),
|
||||
}
|
||||
|
||||
struct AstValidator<'a> {
|
||||
session: &'a Session,
|
||||
|
||||
@@ -56,7 +63,7 @@ struct AstValidator<'a> {
|
||||
/// e.g., `impl Iterator<Item = impl Debug>`.
|
||||
outer_impl_trait: Option<Span>,
|
||||
|
||||
is_tilde_const_allowed: bool,
|
||||
disallow_tilde_const: Option<DisallowTildeConstContext<'a>>,
|
||||
|
||||
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
|
||||
/// or `Foo::Bar<impl Trait>`
|
||||
@@ -93,18 +100,26 @@ impl<'a> AstValidator<'a> {
|
||||
self.is_impl_trait_banned = old;
|
||||
}
|
||||
|
||||
fn with_tilde_const(&mut self, allowed: bool, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.is_tilde_const_allowed, allowed);
|
||||
fn with_tilde_const(
|
||||
&mut self,
|
||||
disallowed: Option<DisallowTildeConstContext<'a>>,
|
||||
f: impl FnOnce(&mut Self),
|
||||
) {
|
||||
let old = mem::replace(&mut self.disallow_tilde_const, disallowed);
|
||||
f(self);
|
||||
self.is_tilde_const_allowed = old;
|
||||
self.disallow_tilde_const = old;
|
||||
}
|
||||
|
||||
fn with_tilde_const_allowed(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
self.with_tilde_const(true, f)
|
||||
self.with_tilde_const(None, f)
|
||||
}
|
||||
|
||||
fn with_banned_tilde_const(&mut self, f: impl FnOnce(&mut Self)) {
|
||||
self.with_tilde_const(false, f)
|
||||
fn with_banned_tilde_const(
|
||||
&mut self,
|
||||
ctx: DisallowTildeConstContext<'a>,
|
||||
f: impl FnOnce(&mut Self),
|
||||
) {
|
||||
self.with_tilde_const(Some(ctx), f)
|
||||
}
|
||||
|
||||
fn with_let_management(
|
||||
@@ -172,7 +187,7 @@ impl<'a> AstValidator<'a> {
|
||||
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
|
||||
let old = mem::replace(&mut self.outer_impl_trait, outer);
|
||||
if outer.is_some() {
|
||||
self.with_banned_tilde_const(f);
|
||||
self.with_banned_tilde_const(DisallowTildeConstContext::ImplTrait, f);
|
||||
} else {
|
||||
f(self);
|
||||
}
|
||||
@@ -197,7 +212,10 @@ impl<'a> AstValidator<'a> {
|
||||
TyKind::ImplTrait(..) => {
|
||||
self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
|
||||
}
|
||||
TyKind::TraitObject(..) => self.with_banned_tilde_const(|this| visit::walk_ty(this, t)),
|
||||
TyKind::TraitObject(..) => self
|
||||
.with_banned_tilde_const(DisallowTildeConstContext::TraitObject, |this| {
|
||||
visit::walk_ty(this, t)
|
||||
}),
|
||||
TyKind::Path(ref qself, ref path) => {
|
||||
// We allow these:
|
||||
// - `Option<impl Trait>`
|
||||
@@ -1411,13 +1429,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
);
|
||||
err.emit();
|
||||
}
|
||||
(_, TraitBoundModifier::MaybeConst) => {
|
||||
if !self.is_tilde_const_allowed {
|
||||
self.err_handler()
|
||||
.struct_span_err(bound.span(), "`~const` is not allowed here")
|
||||
.note("only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions")
|
||||
.emit();
|
||||
}
|
||||
(_, TraitBoundModifier::MaybeConst) if let Some(reason) = &self.disallow_tilde_const => {
|
||||
let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here");
|
||||
match reason {
|
||||
DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"),
|
||||
DisallowTildeConstContext::ImplTrait => err.note("`impl Trait`s cannot have `~const` trait bounds"),
|
||||
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"),
|
||||
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"),
|
||||
};
|
||||
err.emit();
|
||||
}
|
||||
(_, TraitBoundModifier::MaybeConstMaybe) => {
|
||||
self.err_handler()
|
||||
@@ -1523,10 +1543,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
});
|
||||
}
|
||||
|
||||
let tilde_const_allowed = matches!(fk.header(), Some(FnHeader { .. }))
|
||||
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
|
||||
let tilde_const_allowed =
|
||||
matches!(fk.header(), Some(FnHeader { constness: ast::Const::Yes(_), .. }))
|
||||
|| matches!(fk.ctxt(), Some(FnCtxt::Assoc(_)));
|
||||
|
||||
self.with_tilde_const(tilde_const_allowed, |this| visit::walk_fn(this, fk));
|
||||
let disallowed = (!tilde_const_allowed).then(|| DisallowTildeConstContext::Fn(fk));
|
||||
|
||||
self.with_tilde_const(disallowed, |this| visit::walk_fn(this, fk));
|
||||
}
|
||||
|
||||
fn visit_assoc_item(&mut self, item: &'a AssocItem, ctxt: AssocCtxt) {
|
||||
@@ -1770,7 +1793,7 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
|
||||
in_const_trait_impl: false,
|
||||
has_proc_macro_decls: false,
|
||||
outer_impl_trait: None,
|
||||
is_tilde_const_allowed: false,
|
||||
disallow_tilde_const: None,
|
||||
is_impl_trait_banned: false,
|
||||
is_assoc_ty_bound_banned: false,
|
||||
forbidden_let_reason: Some(ForbiddenLetReason::GenericForbidden),
|
||||
|
||||
@@ -35,7 +35,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||
assert_eq!(discr.layout.ty, switch_ty);
|
||||
|
||||
// Branch to the `otherwise` case by default, if no match is found.
|
||||
assert!(!targets.iter().is_empty());
|
||||
let mut target_block = targets.otherwise();
|
||||
|
||||
for (const_int, target) in targets.iter() {
|
||||
|
||||
@@ -190,6 +190,7 @@ impl<'a, 'b> RunCompiler<'a, 'b> {
|
||||
run_compiler(self.at_args, self.callbacks, self.file_loader, self.make_codegen_backend)
|
||||
}
|
||||
}
|
||||
|
||||
fn run_compiler(
|
||||
at_args: &[String],
|
||||
callbacks: &mut (dyn Callbacks + Send),
|
||||
|
||||
@@ -25,7 +25,10 @@ use std::result;
|
||||
|
||||
pub type Result<T> = result::Result<T, ErrorGuaranteed>;
|
||||
|
||||
/// Represents a compiler session.
|
||||
/// Represents a compiler session. Note that every `Compiler` contains a
|
||||
/// `Session`, but `Compiler` also contains some things that cannot be in
|
||||
/// `Session`, due to `Session` being in a crate that has many fewer
|
||||
/// dependencies than this crate.
|
||||
///
|
||||
/// Can be used to run `rustc_interface` queries.
|
||||
/// Created by passing [`Config`] to [`run_compiler`].
|
||||
|
||||
@@ -3,14 +3,8 @@ use libloading::Library;
|
||||
use rustc_ast as ast;
|
||||
use rustc_codegen_ssa::traits::CodegenBackend;
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
#[cfg(parallel_compiler)]
|
||||
use rustc_data_structures::jobserver;
|
||||
use rustc_errors::registry::Registry;
|
||||
#[cfg(parallel_compiler)]
|
||||
use rustc_middle::ty::tls;
|
||||
use rustc_parse::validate_attr;
|
||||
#[cfg(parallel_compiler)]
|
||||
use rustc_query_impl::{QueryContext, QueryCtxt};
|
||||
use rustc_session as session;
|
||||
use rustc_session::config::CheckCfg;
|
||||
use rustc_session::config::{self, CrateType};
|
||||
@@ -25,8 +19,6 @@ use rustc_span::symbol::{sym, Symbol};
|
||||
use std::env;
|
||||
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
|
||||
use std::mem;
|
||||
#[cfg(not(parallel_compiler))]
|
||||
use std::panic;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::OnceLock;
|
||||
@@ -135,13 +127,20 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
|
||||
_threads: usize,
|
||||
f: F,
|
||||
) -> R {
|
||||
// The thread pool is a single thread in the non-parallel compiler.
|
||||
thread::scope(|s| {
|
||||
let mut builder = thread::Builder::new().name("rustc".to_string());
|
||||
if let Some(size) = get_stack_size() {
|
||||
builder = builder.stack_size(size);
|
||||
}
|
||||
// The "thread pool" is a single spawned thread in the non-parallel
|
||||
// compiler. We run on a spawned thread instead of the main thread (a) to
|
||||
// provide control over the stack size, and (b) to increase similarity with
|
||||
// the parallel compiler, in particular to ensure there is no accidental
|
||||
// sharing of data between the main thread and the compilation thread
|
||||
// (which might cause problems for the parallel compiler).
|
||||
let mut builder = thread::Builder::new().name("rustc".to_string());
|
||||
if let Some(size) = get_stack_size() {
|
||||
builder = builder.stack_size(size);
|
||||
}
|
||||
|
||||
// We build the session globals and run `f` on the spawned thread, because
|
||||
// `SessionGlobals` does not impl `Send` in the non-parallel compiler.
|
||||
thread::scope(|s| {
|
||||
// `unwrap` is ok here because `spawn_scoped` only panics if the thread
|
||||
// name contains null bytes.
|
||||
let r = builder
|
||||
@@ -151,55 +150,57 @@ pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
|
||||
|
||||
match r {
|
||||
Ok(v) => v,
|
||||
Err(e) => panic::resume_unwind(e),
|
||||
Err(e) => std::panic::resume_unwind(e),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a new thread and forwards information in thread locals to it.
|
||||
/// The new thread runs the deadlock handler.
|
||||
/// Must only be called when a deadlock is about to happen.
|
||||
#[cfg(parallel_compiler)]
|
||||
unsafe fn handle_deadlock() {
|
||||
let registry = rustc_rayon_core::Registry::current();
|
||||
|
||||
let query_map = tls::with(|tcx| {
|
||||
QueryCtxt::from_tcx(tcx)
|
||||
.try_collect_active_jobs()
|
||||
.expect("active jobs shouldn't be locked in deadlock handler")
|
||||
});
|
||||
thread::spawn(move || rustc_query_impl::deadlock(query_map, ®istry));
|
||||
}
|
||||
|
||||
#[cfg(parallel_compiler)]
|
||||
pub(crate) fn run_in_thread_pool_with_globals<F: FnOnce() -> R + Send, R: Send>(
|
||||
edition: Edition,
|
||||
threads: usize,
|
||||
f: F,
|
||||
) -> R {
|
||||
let mut config = rayon::ThreadPoolBuilder::new()
|
||||
use rustc_data_structures::jobserver;
|
||||
use rustc_middle::ty::tls;
|
||||
use rustc_query_impl::{deadlock, QueryContext, QueryCtxt};
|
||||
|
||||
let mut builder = rayon::ThreadPoolBuilder::new()
|
||||
.thread_name(|_| "rustc".to_string())
|
||||
.acquire_thread_handler(jobserver::acquire_thread)
|
||||
.release_thread_handler(jobserver::release_thread)
|
||||
.num_threads(threads)
|
||||
.deadlock_handler(|| unsafe { handle_deadlock() });
|
||||
|
||||
.deadlock_handler(|| {
|
||||
// On deadlock, creates a new thread and forwards information in thread
|
||||
// locals to it. The new thread runs the deadlock handler.
|
||||
let query_map = tls::with(|tcx| {
|
||||
QueryCtxt::from_tcx(tcx)
|
||||
.try_collect_active_jobs()
|
||||
.expect("active jobs shouldn't be locked in deadlock handler")
|
||||
});
|
||||
let registry = rustc_rayon_core::Registry::current();
|
||||
thread::spawn(move || deadlock(query_map, ®istry));
|
||||
});
|
||||
if let Some(size) = get_stack_size() {
|
||||
config = config.stack_size(size);
|
||||
builder = builder.stack_size(size);
|
||||
}
|
||||
|
||||
let with_pool = move |pool: &rayon::ThreadPool| pool.install(f);
|
||||
|
||||
// We create the session globals on the main thread, then create the thread
|
||||
// pool. Upon creation, each worker thread created gets a copy of the
|
||||
// session globals in TLS. This is possible because `SessionGlobals` impls
|
||||
// `Send` in the parallel compiler.
|
||||
rustc_span::create_session_globals_then(edition, || {
|
||||
rustc_span::with_session_globals(|session_globals| {
|
||||
// The main handler runs for each Rayon worker thread and sets up
|
||||
// the thread local rustc uses. `session_globals` is captured and set
|
||||
// on the new threads.
|
||||
let main_handler = move |thread: rayon::ThreadBuilder| {
|
||||
rustc_span::set_session_globals_then(session_globals, || thread.run())
|
||||
};
|
||||
|
||||
config.build_scoped(main_handler, with_pool).unwrap()
|
||||
builder
|
||||
.build_scoped(
|
||||
// Initialize each new worker thread when created.
|
||||
move |thread: rayon::ThreadBuilder| {
|
||||
rustc_span::set_session_globals_then(session_globals, || thread.run())
|
||||
},
|
||||
// Run `f` on the first thread in the thread pool.
|
||||
move |pool: &rayon::ThreadPool| pool.install(f),
|
||||
)
|
||||
.unwrap()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1939,11 +1939,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
match ty.kind {
|
||||
TyKind::ImplicitSelf => true,
|
||||
TyKind::Path(None, _) => {
|
||||
let path_res = self.r.partial_res_map[&ty.id].expect_full_res();
|
||||
if let Res::SelfTyParam { .. } | Res::SelfTyAlias { .. } = path_res {
|
||||
let path_res = self.r.partial_res_map[&ty.id].full_res();
|
||||
if let Some(Res::SelfTyParam { .. } | Res::SelfTyAlias { .. }) = path_res {
|
||||
return true;
|
||||
}
|
||||
Some(path_res) == self.impl_self
|
||||
self.impl_self.is_some() && path_res == self.impl_self
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
|
||||
@@ -994,14 +994,14 @@ extern "rust-intrinsic" {
|
||||
/// `transmute` is semantically equivalent to a bitwise move of one type
|
||||
/// into another. It copies the bits from the source value into the
|
||||
/// destination value, then forgets the original. Note that source and destination
|
||||
/// are passed by-value, which means if `T` or `U` contain padding, that padding
|
||||
/// are passed by-value, which means if `Src` or `Dst` contain padding, that padding
|
||||
/// is *not* guaranteed to be preserved by `transmute`.
|
||||
///
|
||||
/// Both the argument and the result must be [valid](../../nomicon/what-unsafe-does.html) at
|
||||
/// their given type. Violating this condition leads to [undefined behavior][ub]. The compiler
|
||||
/// will generate code *assuming that you, the programmer, ensure that there will never be
|
||||
/// undefined behavior*. It is therefore your responsibility to guarantee that every value
|
||||
/// passed to `transmute` is valid at both types `T` and `U`. Failing to uphold this condition
|
||||
/// passed to `transmute` is valid at both types `Src` and `Dst`. Failing to uphold this condition
|
||||
/// may lead to unexpected and unstable compilation results. This makes `transmute` **incredibly
|
||||
/// unsafe**. `transmute` should be the absolute last resort.
|
||||
///
|
||||
@@ -1012,7 +1012,7 @@ extern "rust-intrinsic" {
|
||||
///
|
||||
/// Because `transmute` is a by-value operation, alignment of the *transmuted values
|
||||
/// themselves* is not a concern. As with any other function, the compiler already ensures
|
||||
/// both `T` and `U` are properly aligned. However, when transmuting values that *point
|
||||
/// both `Src` and `Dst` are properly aligned. However, when transmuting values that *point
|
||||
/// elsewhere* (such as pointers, references, boxes…), the caller has to ensure proper
|
||||
/// alignment of the pointed-to values.
|
||||
///
|
||||
@@ -1248,7 +1248,7 @@ extern "rust-intrinsic" {
|
||||
#[rustc_allowed_through_unstable_modules]
|
||||
#[rustc_const_stable(feature = "const_transmute", since = "1.56.0")]
|
||||
#[rustc_diagnostic_item = "transmute"]
|
||||
pub fn transmute<T, U>(e: T) -> U;
|
||||
pub fn transmute<Src, Dst>(src: Src) -> Dst;
|
||||
|
||||
/// Returns `true` if the actual type given as `T` requires drop
|
||||
/// glue; returns `false` if the actual type provided for `T`
|
||||
|
||||
+19
-16
@@ -1008,18 +1008,18 @@ pub fn copy<T: Copy>(x: &T) -> T {
|
||||
*x
|
||||
}
|
||||
|
||||
/// Interprets `src` as having type `&U`, and then reads `src` without moving
|
||||
/// Interprets `src` as having type `&Dst`, and then reads `src` without moving
|
||||
/// the contained value.
|
||||
///
|
||||
/// This function will unsafely assume the pointer `src` is valid for [`size_of::<U>`][size_of]
|
||||
/// bytes by transmuting `&T` to `&U` and then reading the `&U` (except that this is done in a way
|
||||
/// that is correct even when `&U` has stricter alignment requirements than `&T`). It will also
|
||||
/// unsafely create a copy of the contained value instead of moving out of `src`.
|
||||
/// This function will unsafely assume the pointer `src` is valid for [`size_of::<Dst>`][size_of]
|
||||
/// bytes by transmuting `&Src` to `&Dst` and then reading the `&Dst` (except that this is done
|
||||
/// in a way that is correct even when `&Dst` has stricter alignment requirements than `&Src`).
|
||||
/// It will also unsafely create a copy of the contained value instead of moving out of `src`.
|
||||
///
|
||||
/// It is not a compile-time error if `T` and `U` have different sizes, but it
|
||||
/// is highly encouraged to only invoke this function where `T` and `U` have the
|
||||
/// same size. This function triggers [undefined behavior][ub] if `U` is larger than
|
||||
/// `T`.
|
||||
/// It is not a compile-time error if `Src` and `Dst` have different sizes, but it
|
||||
/// is highly encouraged to only invoke this function where `Src` and `Dst` have the
|
||||
/// same size. This function triggers [undefined behavior][ub] if `Dst` is larger than
|
||||
/// `Src`.
|
||||
///
|
||||
/// [ub]: ../../reference/behavior-considered-undefined.html
|
||||
///
|
||||
@@ -1052,19 +1052,22 @@ pub fn copy<T: Copy>(x: &T) -> T {
|
||||
#[must_use]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_const_unstable(feature = "const_transmute_copy", issue = "83165")]
|
||||
pub const unsafe fn transmute_copy<T, U>(src: &T) -> U {
|
||||
assert!(size_of::<T>() >= size_of::<U>(), "cannot transmute_copy if U is larger than T");
|
||||
pub const unsafe fn transmute_copy<Src, Dst>(src: &Src) -> Dst {
|
||||
assert!(
|
||||
size_of::<Src>() >= size_of::<Dst>(),
|
||||
"cannot transmute_copy if Dst is larger than Src"
|
||||
);
|
||||
|
||||
// If U has a higher alignment requirement, src might not be suitably aligned.
|
||||
if align_of::<U>() > align_of::<T>() {
|
||||
// If Dst has a higher alignment requirement, src might not be suitably aligned.
|
||||
if align_of::<Dst>() > align_of::<Src>() {
|
||||
// SAFETY: `src` is a reference which is guaranteed to be valid for reads.
|
||||
// The caller must guarantee that the actual transmutation is safe.
|
||||
unsafe { ptr::read_unaligned(src as *const T as *const U) }
|
||||
unsafe { ptr::read_unaligned(src as *const Src as *const Dst) }
|
||||
} else {
|
||||
// SAFETY: `src` is a reference which is guaranteed to be valid for reads.
|
||||
// We just checked that `src as *const U` was properly aligned.
|
||||
// We just checked that `src as *const Dst` was properly aligned.
|
||||
// The caller must guarantee that the actual transmutation is safe.
|
||||
unsafe { ptr::read(src as *const T as *const U) }
|
||||
unsafe { ptr::read(src as *const Src as *const Dst) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,11 @@ fn test_transmute_copy_grow_panics() {
|
||||
payload
|
||||
.downcast::<&'static str>()
|
||||
.and_then(|s| {
|
||||
if *s == "cannot transmute_copy if U is larger than T" { Ok(s) } else { Err(s) }
|
||||
if *s == "cannot transmute_copy if Dst is larger than Src" {
|
||||
Ok(s)
|
||||
} else {
|
||||
Err(s)
|
||||
}
|
||||
})
|
||||
.unwrap_or_else(|p| panic::resume_unwind(p));
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ impl Instant {
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// Previous rust versions panicked when self was earlier than the current time. Currently this
|
||||
/// Previous rust versions panicked when the current time was earlier than self. Currently this
|
||||
/// method returns a Duration of zero in that case. Future versions may reintroduce the panic.
|
||||
/// See [Monotonicity].
|
||||
///
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# armeb-unknown-linux-gnueabi
|
||||
**Tier: 3**
|
||||
|
||||
Target for cross-compiling Linux user-mode applications targetting the ARM BE8 architecture.
|
||||
Target for cross-compiling Linux user-mode applications targeting the ARM BE8 architecture.
|
||||
|
||||
## Overview
|
||||
BE8 architecture retains the same little-endian ordered code-stream used by conventional little endian ARM systems, however the data accesses are in big-endian. BE8 is used primarily in high-performance networking applications where the ability to read packets in their native "Network Byte Order" is important (many network protocols transmit data in big-endian byte order for their wire formats).
|
||||
|
||||
@@ -409,9 +409,12 @@ function loadCss(cssFileName) {
|
||||
break;
|
||||
|
||||
case "+":
|
||||
ev.preventDefault();
|
||||
expandAllDocs();
|
||||
break;
|
||||
case "-":
|
||||
ev.preventDefault();
|
||||
toggleAllDocs();
|
||||
collapseAllDocs();
|
||||
break;
|
||||
|
||||
case "?":
|
||||
@@ -614,15 +617,31 @@ function loadCss(cssFileName) {
|
||||
sidebarElems.appendChild(ul);
|
||||
}
|
||||
|
||||
function expandAllDocs() {
|
||||
const innerToggle = document.getElementById(toggleAllDocsId);
|
||||
removeClass(innerToggle, "will-expand");
|
||||
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
|
||||
if (!hasClass(e, "type-contents-toggle")) {
|
||||
e.open = true;
|
||||
}
|
||||
});
|
||||
innerToggle.title = "collapse all docs";
|
||||
innerToggle.children[0].innerText = "\u2212"; // "\u2212" is "−" minus sign
|
||||
}
|
||||
|
||||
function labelForToggleButton(sectionIsCollapsed) {
|
||||
if (sectionIsCollapsed) {
|
||||
// button will expand the section
|
||||
return "+";
|
||||
}
|
||||
// button will collapse the section
|
||||
// note that this text is also set in the HTML template in ../render/mod.rs
|
||||
return "\u2212"; // "\u2212" is "−" minus sign
|
||||
function collapseAllDocs() {
|
||||
const innerToggle = document.getElementById(toggleAllDocsId);
|
||||
addClass(innerToggle, "will-expand");
|
||||
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
|
||||
if (e.parentNode.id !== "implementations-list" ||
|
||||
(!hasClass(e, "implementors-toggle") &&
|
||||
!hasClass(e, "type-contents-toggle"))
|
||||
) {
|
||||
e.open = false;
|
||||
}
|
||||
});
|
||||
innerToggle.title = "expand all docs";
|
||||
innerToggle.children[0].innerText = "+";
|
||||
}
|
||||
|
||||
function toggleAllDocs() {
|
||||
@@ -630,29 +649,11 @@ function loadCss(cssFileName) {
|
||||
if (!innerToggle) {
|
||||
return;
|
||||
}
|
||||
let sectionIsCollapsed = false;
|
||||
if (hasClass(innerToggle, "will-expand")) {
|
||||
removeClass(innerToggle, "will-expand");
|
||||
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
|
||||
if (!hasClass(e, "type-contents-toggle")) {
|
||||
e.open = true;
|
||||
}
|
||||
});
|
||||
innerToggle.title = "collapse all docs";
|
||||
expandAllDocs();
|
||||
} else {
|
||||
addClass(innerToggle, "will-expand");
|
||||
onEachLazy(document.getElementsByClassName("rustdoc-toggle"), e => {
|
||||
if (e.parentNode.id !== "implementations-list" ||
|
||||
(!hasClass(e, "implementors-toggle") &&
|
||||
!hasClass(e, "type-contents-toggle"))
|
||||
) {
|
||||
e.open = false;
|
||||
}
|
||||
});
|
||||
sectionIsCollapsed = true;
|
||||
innerToggle.title = "expand all docs";
|
||||
collapseAllDocs();
|
||||
}
|
||||
innerToggle.children[0].innerText = labelForToggleButton(sectionIsCollapsed);
|
||||
}
|
||||
|
||||
(function() {
|
||||
|
||||
@@ -11,3 +11,21 @@ press-key: "?"
|
||||
assert-css: ("#help-button .popover", {"display": "block"})
|
||||
press-key: "Escape"
|
||||
assert-css: ("#help-button .popover", {"display": "none"})
|
||||
// Checking doc collapse and expand.
|
||||
// It should be displaying a "-":
|
||||
assert-text: ("#toggle-all-docs", "[\u2212]")
|
||||
press-key: "-"
|
||||
wait-for-text: ("#toggle-all-docs", "[+]")
|
||||
assert-attribute: ("#toggle-all-docs", {"class": "will-expand"})
|
||||
// Pressing it again shouldn't do anything.
|
||||
press-key: "-"
|
||||
assert-text: ("#toggle-all-docs", "[+]")
|
||||
assert-attribute: ("#toggle-all-docs", {"class": "will-expand"})
|
||||
// Expanding now.
|
||||
press-key: "+"
|
||||
wait-for-text: ("#toggle-all-docs", "[\u2212]")
|
||||
assert-attribute: ("#toggle-all-docs", {"class": ""})
|
||||
// Pressing it again shouldn't do anything.
|
||||
press-key: "+"
|
||||
assert-text: ("#toggle-all-docs", "[\u2212]")
|
||||
assert-attribute: ("#toggle-all-docs", {"class": ""})
|
||||
|
||||
@@ -2,12 +2,12 @@ error[E0282]: type annotations needed
|
||||
--> $DIR/issue-6458-3.rs:4:5
|
||||
|
|
||||
LL | mem::transmute(0);
|
||||
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `transmute`
|
||||
| ^^^^^^^^^^^^^^ cannot infer type of the type parameter `Dst` declared on the function `transmute`
|
||||
|
|
||||
help: consider specifying the generic arguments
|
||||
|
|
||||
LL | mem::transmute::<i32, U>(0);
|
||||
| ++++++++++
|
||||
LL | mem::transmute::<i32, Dst>(0);
|
||||
| ++++++++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
struct S {}
|
||||
|
||||
impl S {
|
||||
fn f(self: &S::x) {} //~ ERROR ambiguous associated type
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,9 @@
|
||||
error[E0223]: ambiguous associated type
|
||||
--> $DIR/issue-103202.rs:4:17
|
||||
|
|
||||
LL | fn f(self: &S::x) {}
|
||||
| ^^^^ help: use fully-qualified syntax: `<S as Trait>::x`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0223`.
|
||||
@@ -0,0 +1,9 @@
|
||||
#![feature(const_trait_impl)]
|
||||
|
||||
#[const_trait]
|
||||
trait Bar {}
|
||||
|
||||
fn foo<T>() where T: ~const Bar {}
|
||||
//~^ ERROR `~const` is not allowed
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,14 @@
|
||||
error: `~const` is not allowed here
|
||||
--> $DIR/issue-90052.rs:6:22
|
||||
|
|
||||
LL | fn foo<T>() where T: ~const Bar {}
|
||||
| ^^^^^^^^^^
|
||||
|
|
||||
note: this function is not `const`, so it cannot have `~const` trait bounds
|
||||
--> $DIR/issue-90052.rs:6:4
|
||||
|
|
||||
LL | fn foo<T>() where T: ~const Bar {}
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// check-pass
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(generic_arg_infer)]
|
||||
#![feature(generic_const_exprs)]
|
||||
@@ -24,6 +23,7 @@ impl const Add42 for () {
|
||||
}
|
||||
|
||||
fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
//~^ ERROR `~const` is not allowed here
|
||||
Foo
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
error: `~const` is not allowed here
|
||||
--> $DIR/tilde-const-and-const-params.rs:25:11
|
||||
|
|
||||
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: this function is not `const`, so it cannot have `~const` trait bounds
|
||||
--> $DIR/tilde-const-and-const-params.rs:25:4
|
||||
|
|
||||
LL | fn bar<A: ~const Add42, const N: usize>(_: Foo<N>) -> Foo<{ A::add(N) }> {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
@@ -4,7 +4,7 @@ error: `~const` is not allowed here
|
||||
LL | fn rpit() -> impl ~const T { S }
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
|
||||
= note: `impl Trait`s cannot have `~const` trait bounds
|
||||
|
||||
error: `~const` is not allowed here
|
||||
--> $DIR/tilde-const-invalid-places.rs:12:17
|
||||
@@ -12,7 +12,7 @@ error: `~const` is not allowed here
|
||||
LL | fn apit(_: impl ~const T) {}
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
|
||||
= note: `impl Trait`s cannot have `~const` trait bounds
|
||||
|
||||
error: `~const` is not allowed here
|
||||
--> $DIR/tilde-const-invalid-places.rs:15:50
|
||||
@@ -20,7 +20,7 @@ error: `~const` is not allowed here
|
||||
LL | fn rpit_assoc_bound() -> impl IntoIterator<Item: ~const T> { Some(S) }
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
|
||||
= note: `impl Trait`s cannot have `~const` trait bounds
|
||||
|
||||
error: `~const` is not allowed here
|
||||
--> $DIR/tilde-const-invalid-places.rs:18:48
|
||||
@@ -28,7 +28,7 @@ error: `~const` is not allowed here
|
||||
LL | fn apit_assoc_bound(_: impl IntoIterator<Item: ~const T>) {}
|
||||
| ^^^^^^^^
|
||||
|
|
||||
= note: only allowed on bounds on functions, traits' associated types and functions, const impls and its associated functions
|
||||
= note: `impl Trait`s cannot have `~const` trait bounds
|
||||
|
||||
error: `~const` and `?` are mutually exclusive
|
||||
--> $DIR/tilde-const-invalid-places.rs:21:25
|
||||
|
||||
@@ -217,7 +217,6 @@ trigger_files = [
|
||||
|
||||
[autolabel."A-testsuite"]
|
||||
trigger_files = [
|
||||
"src/test",
|
||||
"src/ci",
|
||||
"src/tools/compiletest",
|
||||
"src/tools/cargotest",
|
||||
|
||||
Reference in New Issue
Block a user