mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 15:01:51 +00:00
Auto merge of #90067 - JohnTitor:rollup-afrjulz, r=JohnTitor
Rollup of 10 pull requests Successful merges: - #86479 (Automatic exponential formatting in Debug) - #87404 (Add support for artifact size profiling) - #87769 (Alloc features cleanup) - #88789 (remove unnecessary bound on Zip specialization impl) - #88860 (Deduplicate panic_fmt) - #90009 (Make more `From` impls `const` (libcore)) - #90018 (Fix rustdoc UI for very long type names) - #90025 (Revert #86011 to fix an incorrect bound check) - #90036 (Remove border-bottom from most docblocks.) - #90060 (Update RELEASES.md) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
42983a28ab
24
Cargo.lock
24
Cargo.lock
@ -2143,6 +2143,20 @@ dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "measureme"
|
||||
version = "10.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd460fad6e55ca82fa0cd9dab0d315294188fd9ec6efbf4105e5635d4872ef9c"
|
||||
dependencies = [
|
||||
"log",
|
||||
"memmap2",
|
||||
"parking_lot",
|
||||
"perf-event-open-sys",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.4.1"
|
||||
@ -2247,7 +2261,7 @@ dependencies = [
|
||||
"hex 0.4.2",
|
||||
"libc",
|
||||
"log",
|
||||
"measureme",
|
||||
"measureme 9.1.2",
|
||||
"rand 0.8.4",
|
||||
"rustc-workspace-hack",
|
||||
"rustc_version 0.4.0",
|
||||
@ -3235,7 +3249,7 @@ dependencies = [
|
||||
"indexmap",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"measureme",
|
||||
"measureme 9.1.2",
|
||||
"memmap2",
|
||||
"parking_lot",
|
||||
"rustc-ap-rustc_graphviz",
|
||||
@ -3674,7 +3688,7 @@ dependencies = [
|
||||
"bitflags",
|
||||
"cstr",
|
||||
"libc",
|
||||
"measureme",
|
||||
"measureme 10.0.0",
|
||||
"rustc-demangle",
|
||||
"rustc_arena",
|
||||
"rustc_ast",
|
||||
@ -3767,7 +3781,7 @@ dependencies = [
|
||||
"indexmap",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"measureme",
|
||||
"measureme 10.0.0",
|
||||
"memmap2",
|
||||
"parking_lot",
|
||||
"rustc-hash",
|
||||
@ -4292,7 +4306,7 @@ dependencies = [
|
||||
name = "rustc_query_impl"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"measureme",
|
||||
"measureme 10.0.0",
|
||||
"rustc-rayon-core",
|
||||
"rustc_ast",
|
||||
"rustc_data_structures",
|
||||
|
@ -77,7 +77,7 @@ Cargo
|
||||
- [Cargo supports specifying a minimum supported Rust version in Cargo.toml.][`rust-version`]
|
||||
This has no effect at present on dependency version selection.
|
||||
We encourage crates to specify their minimum supported Rust version, and we encourage CI systems
|
||||
that support Rust code to include a crate's specified minimum version in the text matrix for that
|
||||
that support Rust code to include a crate's specified minimum version in the test matrix for that
|
||||
crate by default.
|
||||
|
||||
Compatibility notes
|
||||
|
@ -11,7 +11,7 @@ doctest = false
|
||||
bitflags = "1.0"
|
||||
cstr = "0.2"
|
||||
libc = "0.2"
|
||||
measureme = "9.1.0"
|
||||
measureme = "10.0.0"
|
||||
snap = "1"
|
||||
tracing = "0.1"
|
||||
rustc_middle = { path = "../rustc_middle" }
|
||||
|
@ -72,9 +72,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
|
||||
let span = self.find_closest_untracked_caller_location();
|
||||
let (file, line, col) = self.location_triple_for_span(span);
|
||||
return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
|
||||
} else if Some(def_id) == self.tcx.lang_items().panic_fmt()
|
||||
|| Some(def_id) == self.tcx.lang_items().begin_panic_fmt()
|
||||
{
|
||||
} else if Some(def_id) == self.tcx.lang_items().panic_fmt() {
|
||||
// For panic_fmt, call const_panic_fmt instead.
|
||||
if let Some(const_panic_fmt) = self.tcx.lang_items().const_panic_fmt() {
|
||||
return Ok(Some(
|
||||
|
@ -79,7 +79,6 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
|
||||
|| Some(def_id) == tcx.lang_items().panic_display()
|
||||
|| Some(def_id) == tcx.lang_items().begin_panic_fn()
|
||||
|| Some(def_id) == tcx.lang_items().panic_fmt()
|
||||
|| Some(def_id) == tcx.lang_items().begin_panic_fmt()
|
||||
}
|
||||
|
||||
/// Returns `true` if this `DefId` points to one of the lang items that will be handled differently
|
||||
|
@ -23,7 +23,7 @@ rustc-hash = "1.1.0"
|
||||
smallvec = { version = "1.6.1", features = ["union", "may_dangle"] }
|
||||
rustc_index = { path = "../rustc_index", package = "rustc_index" }
|
||||
bitflags = "1.2.1"
|
||||
measureme = "9.1.0"
|
||||
measureme = "10.0.0"
|
||||
libc = "0.2"
|
||||
stacker = "0.1.14"
|
||||
tempfile = "3.2"
|
||||
|
@ -110,12 +110,14 @@ bitflags::bitflags! {
|
||||
const FUNCTION_ARGS = 1 << 6;
|
||||
const LLVM = 1 << 7;
|
||||
const INCR_RESULT_HASHING = 1 << 8;
|
||||
const ARTIFACT_SIZES = 1 << 9;
|
||||
|
||||
const DEFAULT = Self::GENERIC_ACTIVITIES.bits |
|
||||
Self::QUERY_PROVIDERS.bits |
|
||||
Self::QUERY_BLOCKED.bits |
|
||||
Self::INCR_CACHE_LOADS.bits |
|
||||
Self::INCR_RESULT_HASHING.bits;
|
||||
Self::INCR_RESULT_HASHING.bits |
|
||||
Self::ARTIFACT_SIZES.bits;
|
||||
|
||||
const ARGS = Self::QUERY_KEYS.bits | Self::FUNCTION_ARGS.bits;
|
||||
}
|
||||
@ -136,6 +138,7 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
|
||||
("args", EventFilter::ARGS),
|
||||
("llvm", EventFilter::LLVM),
|
||||
("incr-result-hashing", EventFilter::INCR_RESULT_HASHING),
|
||||
("artifact-sizes", EventFilter::ARTIFACT_SIZES),
|
||||
];
|
||||
|
||||
/// Something that uniquely identifies a query invocation.
|
||||
@ -285,6 +288,33 @@ impl SelfProfilerRef {
|
||||
})
|
||||
}
|
||||
|
||||
/// Record the size of an artifact that the compiler produces
|
||||
///
|
||||
/// `artifact_kind` is the class of artifact (e.g., query_cache, object_file, etc.)
|
||||
/// `artifact_name` is an identifier to the specific artifact being stored (usually a filename)
|
||||
#[inline(always)]
|
||||
pub fn artifact_size<A>(&self, artifact_kind: &str, artifact_name: A, size: u64)
|
||||
where
|
||||
A: Borrow<str> + Into<String>,
|
||||
{
|
||||
drop(self.exec(EventFilter::ARTIFACT_SIZES, |profiler| {
|
||||
let builder = EventIdBuilder::new(&profiler.profiler);
|
||||
let event_label = profiler.get_or_alloc_cached_string(artifact_kind);
|
||||
let event_arg = profiler.get_or_alloc_cached_string(artifact_name);
|
||||
let event_id = builder.from_label_and_arg(event_label, event_arg);
|
||||
let thread_id = get_thread_id();
|
||||
|
||||
profiler.profiler.record_integer_event(
|
||||
profiler.artifact_size_event_kind,
|
||||
event_id,
|
||||
thread_id,
|
||||
size,
|
||||
);
|
||||
|
||||
TimingGuard::none()
|
||||
}))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn generic_activity_with_args(
|
||||
&self,
|
||||
@ -372,7 +402,7 @@ impl SelfProfilerRef {
|
||||
) {
|
||||
drop(self.exec(event_filter, |profiler| {
|
||||
let event_id = StringId::new_virtual(query_invocation_id.0);
|
||||
let thread_id = std::thread::current().id().as_u64().get() as u32;
|
||||
let thread_id = get_thread_id();
|
||||
|
||||
profiler.profiler.record_instant_event(
|
||||
event_kind(profiler),
|
||||
@ -425,6 +455,7 @@ pub struct SelfProfiler {
|
||||
incremental_result_hashing_event_kind: StringId,
|
||||
query_blocked_event_kind: StringId,
|
||||
query_cache_hit_event_kind: StringId,
|
||||
artifact_size_event_kind: StringId,
|
||||
}
|
||||
|
||||
impl SelfProfiler {
|
||||
@ -447,6 +478,7 @@ impl SelfProfiler {
|
||||
profiler.alloc_string("IncrementalResultHashing");
|
||||
let query_blocked_event_kind = profiler.alloc_string("QueryBlocked");
|
||||
let query_cache_hit_event_kind = profiler.alloc_string("QueryCacheHit");
|
||||
let artifact_size_event_kind = profiler.alloc_string("ArtifactSize");
|
||||
|
||||
let mut event_filter_mask = EventFilter::empty();
|
||||
|
||||
@ -491,6 +523,7 @@ impl SelfProfiler {
|
||||
incremental_result_hashing_event_kind,
|
||||
query_blocked_event_kind,
|
||||
query_cache_hit_event_kind,
|
||||
artifact_size_event_kind,
|
||||
})
|
||||
}
|
||||
|
||||
@ -561,7 +594,7 @@ impl<'a> TimingGuard<'a> {
|
||||
event_kind: StringId,
|
||||
event_id: EventId,
|
||||
) -> TimingGuard<'a> {
|
||||
let thread_id = std::thread::current().id().as_u64().get() as u32;
|
||||
let thread_id = get_thread_id();
|
||||
let raw_profiler = &profiler.profiler;
|
||||
let timing_guard =
|
||||
raw_profiler.start_recording_interval_event(event_kind, event_id, thread_id);
|
||||
@ -655,6 +688,10 @@ pub fn duration_to_secs_str(dur: std::time::Duration) -> String {
|
||||
format!("{:.3}", dur.as_secs_f64())
|
||||
}
|
||||
|
||||
fn get_thread_id() -> u32 {
|
||||
std::thread::current().id().as_u64().get() as u32
|
||||
}
|
||||
|
||||
// Memory reporting
|
||||
cfg_if! {
|
||||
if #[cfg(windows)] {
|
||||
|
@ -292,7 +292,6 @@ language_item_table! {
|
||||
PanicImpl, sym::panic_impl, panic_impl, Target::Fn, GenericRequirement::None;
|
||||
/// libstd panic entry point. Necessary for const eval to be able to catch it
|
||||
BeginPanic, sym::begin_panic, begin_panic_fn, Target::Fn, GenericRequirement::None;
|
||||
BeginPanicFmt, sym::begin_panic_fmt, begin_panic_fmt, Target::Fn, GenericRequirement::None;
|
||||
|
||||
ExchangeMalloc, sym::exchange_malloc, exchange_malloc_fn, Target::Fn, GenericRequirement::None;
|
||||
BoxFree, sym::box_free, box_free_fn, Target::Fn, GenericRequirement::Minimum(1);
|
||||
|
@ -95,6 +95,12 @@ where
|
||||
return;
|
||||
}
|
||||
|
||||
sess.prof.artifact_size(
|
||||
&name.replace(' ', "_"),
|
||||
path_buf.file_name().unwrap().to_string_lossy(),
|
||||
encoder.position() as u64,
|
||||
);
|
||||
|
||||
debug!("save: data written to disk successfully");
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
measureme = "9.0.0"
|
||||
measureme = "10.0.0"
|
||||
rustc-rayon-core = "0.3.1"
|
||||
tracing = "0.1"
|
||||
rustc_ast = { path = "../rustc_ast" }
|
||||
|
@ -222,7 +222,7 @@ impl<K: DepKind> EncoderState<K> {
|
||||
index
|
||||
}
|
||||
|
||||
fn finish(self) -> FileEncodeResult {
|
||||
fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
|
||||
let Self { mut encoder, total_node_count, total_edge_count, result, stats: _ } = self;
|
||||
let () = result?;
|
||||
|
||||
@ -235,7 +235,11 @@ impl<K: DepKind> EncoderState<K> {
|
||||
IntEncodedWithFixedSize(edge_count).encode(&mut encoder)?;
|
||||
debug!("position: {:?}", encoder.position());
|
||||
// Drop the encoder so that nothing is written after the counts.
|
||||
encoder.flush()
|
||||
let result = encoder.flush();
|
||||
// FIXME(rylev): we hardcode the dep graph file name so we don't need a dependency on
|
||||
// rustc_incremental just for that.
|
||||
profiler.artifact_size("dep_graph", "dep-graph.bin", encoder.position() as u64);
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
@ -332,6 +336,6 @@ impl<K: DepKind + Encodable<FileEncoder>> GraphEncoder<K> {
|
||||
|
||||
pub fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
|
||||
let _prof_timer = profiler.generic_activity("incr_comp_encode_dep_graph");
|
||||
self.status.into_inner().finish()
|
||||
self.status.into_inner().finish(profiler)
|
||||
}
|
||||
}
|
||||
|
@ -1283,7 +1283,7 @@ options! {
|
||||
"specify the events recorded by the self profiler;
|
||||
for example: `-Z self-profile-events=default,query-keys`
|
||||
all options: none, all, default, generic-activity, query-provider, query-cache-hit
|
||||
query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm"),
|
||||
query-blocked, incr-cache-load, incr-result-hashing, query-keys, function-args, args, llvm, artifact-sizes"),
|
||||
share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
|
||||
"make the current crate share its generic instantiations"),
|
||||
show_span: Option<String> = (None, parse_opt_string, [TRACKED],
|
||||
|
@ -355,7 +355,6 @@ symbols! {
|
||||
await_macro,
|
||||
bang,
|
||||
begin_panic,
|
||||
begin_panic_fmt,
|
||||
bench,
|
||||
bin,
|
||||
bind_by_move_pattern_guards,
|
||||
|
@ -64,16 +64,16 @@ impl<'tcx> Bounds<'tcx> {
|
||||
})
|
||||
});
|
||||
|
||||
self.region_bounds
|
||||
.iter()
|
||||
.map(|&(region_bound, span)| {
|
||||
sized_predicate
|
||||
.into_iter()
|
||||
.chain(self.region_bounds.iter().map(|&(region_bound, span)| {
|
||||
(
|
||||
region_bound
|
||||
.map_bound(|region_bound| ty::OutlivesPredicate(param_ty, region_bound))
|
||||
.to_predicate(tcx),
|
||||
span,
|
||||
)
|
||||
})
|
||||
}))
|
||||
.chain(self.trait_bounds.iter().map(|&(bound_trait_ref, span, constness)| {
|
||||
let predicate = bound_trait_ref.with_constness(constness).to_predicate(tcx);
|
||||
(predicate, span)
|
||||
@ -83,7 +83,6 @@ impl<'tcx> Bounds<'tcx> {
|
||||
.iter()
|
||||
.map(|&(projection, span)| (projection.to_predicate(tcx), span)),
|
||||
)
|
||||
.chain(sized_predicate.into_iter())
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
@ -80,87 +80,90 @@
|
||||
)]
|
||||
#![no_std]
|
||||
#![needs_allocator]
|
||||
#![warn(deprecated_in_future)]
|
||||
#![warn(missing_docs)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![allow(explicit_outlives_requirements)]
|
||||
//
|
||||
// Lints:
|
||||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
#![feature(rustc_allow_const_fn_unstable)]
|
||||
#![cfg_attr(not(test), feature(generator_trait))]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![cfg_attr(test, feature(new_uninit))]
|
||||
#![warn(deprecated_in_future)]
|
||||
#![warn(missing_debug_implementations)]
|
||||
#![warn(missing_docs)]
|
||||
#![allow(explicit_outlives_requirements)]
|
||||
//
|
||||
// Library features:
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(allocator_api)]
|
||||
#![feature(array_chunks)]
|
||||
#![feature(array_methods)]
|
||||
#![feature(array_windows)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(arbitrary_self_types)]
|
||||
#![feature(async_stream)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cfg_sanitize)]
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(coerce_unsized)]
|
||||
#![cfg_attr(not(no_global_oom_handling), feature(const_btree_new))]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![feature(cow_is_borrowed)]
|
||||
#![feature(const_cow_is_borrowed)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(destructuring_assignment)]
|
||||
#![feature(dispatch_from_dyn)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(dispatch_from_dyn)]
|
||||
#![feature(exact_size_is_empty)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(extend_one)]
|
||||
#![feature(fmt_internals)]
|
||||
#![feature(fn_traits)]
|
||||
#![feature(fundamental)]
|
||||
#![feature(inplace_iteration)]
|
||||
#![feature(iter_advance_by)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(layout_for_ptr)]
|
||||
#![feature(maybe_uninit_extra)]
|
||||
#![feature(maybe_uninit_slice)]
|
||||
#![cfg_attr(test, feature(new_uninit))]
|
||||
#![feature(nonnull_slice_from_raw_parts)]
|
||||
#![feature(option_result_unwrap_unchecked)]
|
||||
#![feature(pattern)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(receiver_trait)]
|
||||
#![feature(set_ptr_value)]
|
||||
#![feature(slice_group_by)]
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(slice_ptr_len)]
|
||||
#![feature(slice_range)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(trusted_random_access)]
|
||||
#![feature(try_trait_v2)]
|
||||
#![feature(unicode_internals)]
|
||||
#![feature(unsize)]
|
||||
//
|
||||
// Language features:
|
||||
#![feature(allocator_internals)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(cfg_sanitize)]
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(const_fn_trait_bound)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(destructuring_assignment)]
|
||||
#![feature(dropck_eyepatch)]
|
||||
#![feature(exclusive_range_pattern)]
|
||||
#![feature(fundamental)]
|
||||
#![cfg_attr(not(test), feature(generator_trait))]
|
||||
#![feature(lang_items)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)] // Not necessary, but here to test the `nll` feature.
|
||||
#![feature(rustc_allow_const_fn_unstable)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(staged_api)]
|
||||
#![cfg_attr(test, feature(test))]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unsized_fn_params)]
|
||||
//
|
||||
// Rustdoc features:
|
||||
#![feature(doc_cfg)]
|
||||
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
|
||||
// Technically, this is a bug in rustdoc: rustdoc sees the documentation on `#[lang = slice_alloc]`
|
||||
// blocks is for `&[T]`, which also has documentation using this feature in `core`, and gets mad
|
||||
// that the feature-gate isn't enabled. Ideally, it wouldn't check for the feature gate for docs
|
||||
// from other crates, but since this can only appear for lang items, it doesn't seem worth fixing.
|
||||
#![feature(intra_doc_pointers)]
|
||||
#![feature(iter_advance_by)]
|
||||
#![feature(iter_zip)]
|
||||
#![feature(lang_items)]
|
||||
#![feature(layout_for_ptr)]
|
||||
#![feature(negative_impls)]
|
||||
#![feature(never_type)]
|
||||
#![feature(nll)]
|
||||
#![feature(nonnull_slice_from_raw_parts)]
|
||||
#![feature(auto_traits)]
|
||||
#![feature(option_result_unwrap_unchecked)]
|
||||
#![feature(pattern)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(receiver_trait)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(set_ptr_value)]
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(slice_ptr_len)]
|
||||
#![feature(slice_range)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(str_internals)]
|
||||
#![feature(trusted_len)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unicode_internals)]
|
||||
#![feature(unsize)]
|
||||
#![feature(unsized_fn_params)]
|
||||
#![feature(allocator_internals)]
|
||||
#![feature(slice_partition_dedup)]
|
||||
#![feature(maybe_uninit_extra, maybe_uninit_slice, maybe_uninit_uninit_array)]
|
||||
#![feature(alloc_layout_extra)]
|
||||
#![feature(trusted_random_access)]
|
||||
#![feature(try_trait_v2)]
|
||||
#![feature(associated_type_bounds)]
|
||||
#![feature(slice_group_by)]
|
||||
#![feature(decl_macro)]
|
||||
#![feature(doc_cfg)]
|
||||
#![cfg_attr(not(bootstrap), feature(doc_cfg_hide))]
|
||||
// Allow testing this library
|
||||
|
||||
// Allow testing this library
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate std;
|
||||
|
@ -125,7 +125,8 @@ impl TryFromSliceError {
|
||||
}
|
||||
|
||||
#[stable(feature = "try_from_slice_error", since = "1.36.0")]
|
||||
impl From<Infallible> for TryFromSliceError {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<Infallible> for TryFromSliceError {
|
||||
fn from(x: Infallible) -> TryFromSliceError {
|
||||
match x {}
|
||||
}
|
||||
|
@ -308,7 +308,8 @@ impl<T: Ord + Copy> Ord for Cell<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "cell_from", since = "1.12.0")]
|
||||
impl<T> From<T> for Cell<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<T> for Cell<T> {
|
||||
fn from(t: T) -> Cell<T> {
|
||||
Cell::new(t)
|
||||
}
|
||||
@ -1236,7 +1237,8 @@ impl<T: ?Sized + Ord> Ord for RefCell<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "cell_from", since = "1.12.0")]
|
||||
impl<T> From<T> for RefCell<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<T> for RefCell<T> {
|
||||
fn from(t: T) -> RefCell<T> {
|
||||
RefCell::new(t)
|
||||
}
|
||||
@ -1976,7 +1978,8 @@ impl<T: Default> Default for UnsafeCell<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "cell_from", since = "1.12.0")]
|
||||
impl<T> From<T> for UnsafeCell<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<T> for UnsafeCell<T> {
|
||||
fn from(t: T) -> UnsafeCell<T> {
|
||||
UnsafeCell::new(t)
|
||||
}
|
||||
|
@ -97,7 +97,8 @@ pub unsafe fn from_u32_unchecked(i: u32) -> char {
|
||||
}
|
||||
|
||||
#[stable(feature = "char_convert", since = "1.13.0")]
|
||||
impl From<char> for u32 {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<char> for u32 {
|
||||
/// Converts a [`char`] into a [`u32`].
|
||||
///
|
||||
/// # Examples
|
||||
@ -116,7 +117,8 @@ impl From<char> for u32 {
|
||||
}
|
||||
|
||||
#[stable(feature = "more_char_conversions", since = "1.51.0")]
|
||||
impl From<char> for u64 {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<char> for u64 {
|
||||
/// Converts a [`char`] into a [`u64`].
|
||||
///
|
||||
/// # Examples
|
||||
@ -137,7 +139,8 @@ impl From<char> for u64 {
|
||||
}
|
||||
|
||||
#[stable(feature = "more_char_conversions", since = "1.51.0")]
|
||||
impl From<char> for u128 {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<char> for u128 {
|
||||
/// Converts a [`char`] into a [`u128`].
|
||||
///
|
||||
/// # Examples
|
||||
@ -176,7 +179,8 @@ impl From<char> for u128 {
|
||||
/// for a superset of Windows-1252 that fills the remaining blanks with corresponding
|
||||
/// C0 and C1 control codes.
|
||||
#[stable(feature = "char_convert", since = "1.13.0")]
|
||||
impl From<u8> for char {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<u8> for char {
|
||||
/// Converts a [`u8`] into a [`char`].
|
||||
///
|
||||
/// # Examples
|
||||
|
@ -545,7 +545,8 @@ where
|
||||
|
||||
// From (and thus Into) is reflexive
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> From<T> for T {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<T> for T {
|
||||
fn from(t: T) -> T {
|
||||
t
|
||||
}
|
||||
@ -560,7 +561,8 @@ impl<T> From<T> for T {
|
||||
#[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead.
|
||||
#[rustc_reservation_impl = "permitting this impl would forbid us from adding \
|
||||
`impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
|
||||
impl<T> From<!> for T {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<!> for T {
|
||||
fn from(t: !) -> T {
|
||||
t
|
||||
}
|
||||
@ -726,7 +728,8 @@ impl Ord for Infallible {
|
||||
}
|
||||
|
||||
#[stable(feature = "convert_infallible", since = "1.34.0")]
|
||||
impl From<!> for Infallible {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<!> for Infallible {
|
||||
fn from(x: !) -> Self {
|
||||
x
|
||||
}
|
||||
|
@ -3,6 +3,26 @@ use crate::mem::MaybeUninit;
|
||||
use crate::num::flt2dec;
|
||||
use crate::num::fmt as numfmt;
|
||||
|
||||
#[doc(hidden)]
|
||||
trait GeneralFormat: PartialOrd {
|
||||
/// Determines if a value should use exponential based on its magnitude, given the precondition
|
||||
/// that it will not be rounded any further before it is displayed.
|
||||
fn already_rounded_value_should_use_exponential(&self) -> bool;
|
||||
}
|
||||
|
||||
macro_rules! impl_general_format {
|
||||
($($t:ident)*) => {
|
||||
$(impl GeneralFormat for $t {
|
||||
fn already_rounded_value_should_use_exponential(&self) -> bool {
|
||||
let abs = $t::abs_private(*self);
|
||||
(abs != 0.0 && abs < 1e-4) || abs >= 1e+16
|
||||
}
|
||||
})*
|
||||
}
|
||||
}
|
||||
|
||||
impl_general_format! { f32 f64 }
|
||||
|
||||
// Don't inline this so callers don't use the stack space this function
|
||||
// requires unless they have to.
|
||||
#[inline(never)]
|
||||
@ -54,8 +74,7 @@ where
|
||||
fmt.pad_formatted_parts(&formatted)
|
||||
}
|
||||
|
||||
// Common code of floating point Debug and Display.
|
||||
fn float_to_decimal_common<T>(fmt: &mut Formatter<'_>, num: &T, min_precision: usize) -> Result
|
||||
fn float_to_decimal_display<T>(fmt: &mut Formatter<'_>, num: &T) -> Result
|
||||
where
|
||||
T: flt2dec::DecodableFloat,
|
||||
{
|
||||
@ -68,6 +87,7 @@ where
|
||||
if let Some(precision) = fmt.precision {
|
||||
float_to_decimal_common_exact(fmt, num, sign, precision)
|
||||
} else {
|
||||
let min_precision = 0;
|
||||
float_to_decimal_common_shortest(fmt, num, sign, min_precision)
|
||||
}
|
||||
}
|
||||
@ -145,19 +165,44 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn float_to_general_debug<T>(fmt: &mut Formatter<'_>, num: &T) -> Result
|
||||
where
|
||||
T: flt2dec::DecodableFloat + GeneralFormat,
|
||||
{
|
||||
let force_sign = fmt.sign_plus();
|
||||
let sign = match force_sign {
|
||||
false => flt2dec::Sign::Minus,
|
||||
true => flt2dec::Sign::MinusPlus,
|
||||
};
|
||||
|
||||
if let Some(precision) = fmt.precision {
|
||||
// this behavior of {:.PREC?} predates exponential formatting for {:?}
|
||||
float_to_decimal_common_exact(fmt, num, sign, precision)
|
||||
} else {
|
||||
// since there is no precision, there will be no rounding
|
||||
if num.already_rounded_value_should_use_exponential() {
|
||||
let upper = false;
|
||||
float_to_exponential_common_shortest(fmt, num, sign, upper)
|
||||
} else {
|
||||
let min_precision = 1;
|
||||
float_to_decimal_common_shortest(fmt, num, sign, min_precision)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! floating {
|
||||
($ty:ident) => {
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Debug for $ty {
|
||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
|
||||
float_to_decimal_common(fmt, self, 1)
|
||||
float_to_general_debug(fmt, self)
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl Display for $ty {
|
||||
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result {
|
||||
float_to_decimal_common(fmt, self, 0)
|
||||
float_to_decimal_display(fmt, self)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -427,13 +427,9 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Since SourceIter forwards the left hand side we do the same here
|
||||
#[unstable(issue = "none", feature = "inplace_iteration")]
|
||||
// Limited to Item: Copy since interaction between Zip's use of TrustedRandomAccess
|
||||
// and Drop implementation of the source is unclear.
|
||||
//
|
||||
// An additional method returning the number of times the source has been logically advanced
|
||||
// (without calling next()) would be needed to properly drop the remainder of the source.
|
||||
unsafe impl<A: InPlaceIterable, B: Iterator> InPlaceIterable for Zip<A, B> where A::Item: Copy {}
|
||||
unsafe impl<A: InPlaceIterable, B: Iterator> InPlaceIterable for Zip<A, B> {}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: Debug, B: Debug> Debug for Zip<A, B> {
|
||||
|
@ -74,7 +74,7 @@ impl<T: PartialEq> PartialEq for OnceCell<T> {
|
||||
impl<T: Eq> Eq for OnceCell<T> {}
|
||||
|
||||
#[unstable(feature = "once_cell", issue = "74465")]
|
||||
impl<T> From<T> for OnceCell<T> {
|
||||
impl<T> const From<T> for OnceCell<T> {
|
||||
fn from(value: T) -> Self {
|
||||
OnceCell { inner: UnsafeCell::new(Some(value)) }
|
||||
}
|
||||
|
@ -29,14 +29,15 @@ impl fmt::Display for TryFromIntError {
|
||||
}
|
||||
|
||||
#[stable(feature = "try_from", since = "1.34.0")]
|
||||
impl From<Infallible> for TryFromIntError {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<Infallible> for TryFromIntError {
|
||||
fn from(x: Infallible) -> TryFromIntError {
|
||||
match x {}
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "never_type", issue = "35121")]
|
||||
impl From<!> for TryFromIntError {
|
||||
impl const From<!> for TryFromIntError {
|
||||
fn from(never: !) -> TryFromIntError {
|
||||
// Match rather than coerce to make sure that code like
|
||||
// `From<Infallible> for TryFromIntError` above will keep working
|
||||
|
@ -449,7 +449,7 @@ impl f32 {
|
||||
// private use internally.
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
|
||||
const fn abs_private(self) -> f32 {
|
||||
pub(crate) const fn abs_private(self) -> f32 {
|
||||
f32::from_bits(self.to_bits() & 0x7fff_ffff)
|
||||
}
|
||||
|
||||
|
@ -448,7 +448,7 @@ impl f64 {
|
||||
// private use internally.
|
||||
#[inline]
|
||||
#[rustc_const_unstable(feature = "const_float_classify", issue = "72505")]
|
||||
const fn abs_private(self) -> f64 {
|
||||
pub(crate) const fn abs_private(self) -> f64 {
|
||||
f64::from_bits(self.to_bits() & 0x7fff_ffff_ffff_ffff)
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,8 @@ macro_rules! nonzero_integers {
|
||||
}
|
||||
|
||||
#[stable(feature = "from_nonzero", since = "1.31.0")]
|
||||
impl From<$Ty> for $Int {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<$Ty> for $Int {
|
||||
#[doc = concat!("Converts a `", stringify!($Ty), "` into an `", stringify!($Int), "`")]
|
||||
#[inline]
|
||||
fn from(nonzero: $Ty) -> Self {
|
||||
|
@ -1723,7 +1723,8 @@ impl<'a, T> IntoIterator for &'a mut Option<T> {
|
||||
}
|
||||
|
||||
#[stable(since = "1.12.0", feature = "option_from")]
|
||||
impl<T> From<T> for Option<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<T> for Option<T> {
|
||||
/// Moves `val` into a new [`Some`].
|
||||
///
|
||||
/// # Examples
|
||||
@ -1739,7 +1740,8 @@ impl<T> From<T> for Option<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
|
||||
impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<'a, T> const From<&'a Option<T>> for Option<&'a T> {
|
||||
/// Converts from `&Option<T>` to `Option<&T>`.
|
||||
///
|
||||
/// # Examples
|
||||
@ -1766,7 +1768,8 @@ impl<'a, T> From<&'a Option<T>> for Option<&'a T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "option_ref_from_ref_option", since = "1.30.0")]
|
||||
impl<'a, T> From<&'a mut Option<T>> for Option<&'a mut T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<'a, T> const From<&'a mut Option<T>> for Option<&'a mut T> {
|
||||
/// Converts from `&mut Option<T>` to `Option<&mut T>`
|
||||
///
|
||||
/// # Examples
|
||||
@ -2052,7 +2055,7 @@ impl<T> ops::Try for Option<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "try_trait_v2", issue = "84277")]
|
||||
impl<T> ops::FromResidual for Option<T> {
|
||||
impl<T> const ops::FromResidual for Option<T> {
|
||||
#[inline]
|
||||
fn from_residual(residual: Option<convert::Infallible>) -> Self {
|
||||
match residual {
|
||||
|
@ -121,7 +121,7 @@ impl<'a> PanicInfo<'a> {
|
||||
#[stable(feature = "panic_hooks", since = "1.10.0")]
|
||||
pub fn location(&self) -> Option<&Location<'_>> {
|
||||
// NOTE: If this is changed to sometimes return None,
|
||||
// deal with that case in std::panicking::default_hook and std::panicking::begin_panic_fmt.
|
||||
// deal with that case in std::panicking::default_hook and core::panicking::panic_fmt.
|
||||
Some(&self.location)
|
||||
}
|
||||
}
|
||||
|
@ -76,8 +76,15 @@ fn panic_bounds_check(index: usize, len: usize) -> ! {
|
||||
panic!("index out of bounds: the len is {} but the index is {}", len, index)
|
||||
}
|
||||
|
||||
/// The underlying implementation of libcore's `panic!` macro when formatting is used.
|
||||
/// The entry point for panicking with a formatted message.
|
||||
///
|
||||
/// This is designed to reduce the amount of code required at the call
|
||||
/// site as much as possible (so that `panic!()` has as low an impact
|
||||
/// on (e.g.) the inlining of other functions as possible), by moving
|
||||
/// the actual formatting into this shared place.
|
||||
#[cold]
|
||||
// If panic_immediate_abort, inline the abort call,
|
||||
// otherwise avoid inlining because of it is cold path.
|
||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||
#[track_caller]
|
||||
|
@ -698,7 +698,8 @@ impl<T: ?Sized> hash::Hash for NonNull<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T: ?Sized> const From<Unique<T>> for NonNull<T> {
|
||||
#[inline]
|
||||
fn from(unique: Unique<T>) -> Self {
|
||||
// SAFETY: A Unique pointer cannot be null, so the conditions for
|
||||
@ -708,7 +709,8 @@ impl<T: ?Sized> From<Unique<T>> for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T: ?Sized> const From<&mut T> for NonNull<T> {
|
||||
#[inline]
|
||||
fn from(reference: &mut T) -> Self {
|
||||
// SAFETY: A mutable reference cannot be null.
|
||||
@ -717,7 +719,8 @@ impl<T: ?Sized> From<&mut T> for NonNull<T> {
|
||||
}
|
||||
|
||||
#[stable(feature = "nonnull", since = "1.25.0")]
|
||||
impl<T: ?Sized> From<&T> for NonNull<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T: ?Sized> const From<&T> for NonNull<T> {
|
||||
#[inline]
|
||||
fn from(reference: &T) -> Self {
|
||||
// SAFETY: A reference cannot be null, so the conditions for
|
||||
|
@ -176,7 +176,7 @@ impl<T: ?Sized> fmt::Pointer for Unique<T> {
|
||||
}
|
||||
|
||||
#[unstable(feature = "ptr_internals", issue = "none")]
|
||||
impl<T: ?Sized> From<&mut T> for Unique<T> {
|
||||
impl<T: ?Sized> const From<&mut T> for Unique<T> {
|
||||
#[inline]
|
||||
fn from(reference: &mut T) -> Self {
|
||||
// SAFETY: A mutable reference cannot be null
|
||||
|
@ -1273,7 +1273,8 @@ impl<T> AtomicPtr<T> {
|
||||
|
||||
#[cfg(target_has_atomic_load_store = "8")]
|
||||
#[stable(feature = "atomic_bool_from", since = "1.24.0")]
|
||||
impl From<bool> for AtomicBool {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<bool> for AtomicBool {
|
||||
/// Converts a `bool` into an `AtomicBool`.
|
||||
///
|
||||
/// # Examples
|
||||
@ -1291,7 +1292,8 @@ impl From<bool> for AtomicBool {
|
||||
|
||||
#[cfg(target_has_atomic_load_store = "ptr")]
|
||||
#[stable(feature = "atomic_from", since = "1.23.0")]
|
||||
impl<T> From<*mut T> for AtomicPtr<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<*mut T> for AtomicPtr<T> {
|
||||
#[inline]
|
||||
fn from(p: *mut T) -> Self {
|
||||
Self::new(p)
|
||||
@ -1363,7 +1365,8 @@ macro_rules! atomic_int {
|
||||
}
|
||||
|
||||
#[$stable_from]
|
||||
impl From<$int_type> for $atomic_type {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl const From<$int_type> for $atomic_type {
|
||||
#[doc = concat!("Converts an `", stringify!($int_type), "` into an `", stringify!($atomic_type), "`.")]
|
||||
#[inline]
|
||||
fn from(v: $int_type) -> Self { Self::new(v) }
|
||||
|
@ -241,7 +241,8 @@ impl<T, E> Poll<Option<Result<T, E>>> {
|
||||
}
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
impl<T> From<T> for Poll<T> {
|
||||
#[rustc_const_unstable(feature = "const_convert", issue = "88674")]
|
||||
impl<T> const From<T> for Poll<T> {
|
||||
/// Convert to a `Ready` variant.
|
||||
///
|
||||
/// # Example
|
||||
|
@ -220,3 +220,10 @@ fn atomic_compare_exchange() {
|
||||
ATOMIC.compare_exchange_weak(0, 1, SeqCst, Acquire).ok();
|
||||
ATOMIC.compare_exchange_weak(0, 1, SeqCst, SeqCst).ok();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn atomic_const_from() {
|
||||
const _ATOMIC_U8: AtomicU8 = AtomicU8::from(1);
|
||||
const _ATOMIC_BOOL: AtomicBool = AtomicBool::from(true);
|
||||
const _ATOMIC_PTR: AtomicPtr<u32> = AtomicPtr::from(core::ptr::null_mut());
|
||||
}
|
||||
|
@ -465,4 +465,13 @@ fn const_cells() {
|
||||
|
||||
const CELL: Cell<i32> = Cell::new(3);
|
||||
const _: i32 = CELL.into_inner();
|
||||
|
||||
const UNSAFE_CELL_FROM: UnsafeCell<i32> = UnsafeCell::from(3);
|
||||
const _: i32 = UNSAFE_CELL.into_inner();
|
||||
|
||||
const REF_CELL_FROM: RefCell<i32> = RefCell::from(3);
|
||||
const _: i32 = REF_CELL.into_inner();
|
||||
|
||||
const CELL_FROM: Cell<i32> = Cell::from(3);
|
||||
const _: i32 = CELL.into_inner();
|
||||
}
|
||||
|
@ -5,6 +5,8 @@ use std::{char, str};
|
||||
#[test]
|
||||
fn test_convert() {
|
||||
assert_eq!(u32::from('a'), 0x61);
|
||||
assert_eq!(u64::from('b'), 0x62);
|
||||
assert_eq!(u128::from('c'), 0x63);
|
||||
assert_eq!(char::from(b'\0'), '\0');
|
||||
assert_eq!(char::from(b'a'), 'a');
|
||||
assert_eq!(char::from(b'\xFF'), '\u{FF}');
|
||||
@ -19,6 +21,16 @@ fn test_convert() {
|
||||
assert!(char::try_from(0xFFFF_FFFF_u32).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
const fn test_convert_const() {
|
||||
assert!(u32::from('a') == 0x61);
|
||||
assert!(u64::from('b') == 0x62);
|
||||
assert!(u128::from('c') == 0x63);
|
||||
assert!(char::from(b'\0') == '\0');
|
||||
assert!(char::from(b'a') == 'a');
|
||||
assert!(char::from(b'\xFF') == '\u{FF}');
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_str() {
|
||||
assert_eq!(char::from_str("a").unwrap(), 'a');
|
||||
|
@ -12,6 +12,16 @@ fn test_format_f64() {
|
||||
assert_eq!("1.23456789E3", format!("{:E}", 1234.56789f64));
|
||||
assert_eq!("0.0", format!("{:?}", 0.0f64));
|
||||
assert_eq!("1.01", format!("{:?}", 1.01f64));
|
||||
|
||||
let high_cutoff = 1e16_f64;
|
||||
assert_eq!("1e16", format!("{:?}", high_cutoff));
|
||||
assert_eq!("-1e16", format!("{:?}", -high_cutoff));
|
||||
assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f64::EPSILON))));
|
||||
assert_eq!("-3.0", format!("{:?}", -3f64));
|
||||
assert_eq!("0.0001", format!("{:?}", 0.0001f64));
|
||||
assert_eq!("9e-5", format!("{:?}", 0.00009f64));
|
||||
assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f64));
|
||||
assert_eq!("1234.6", format!("{:.1?}", 1234.56789f64));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -28,4 +38,18 @@ fn test_format_f32() {
|
||||
assert_eq!("1.2345679E3", format!("{:E}", 1234.56789f32));
|
||||
assert_eq!("0.0", format!("{:?}", 0.0f32));
|
||||
assert_eq!("1.01", format!("{:?}", 1.01f32));
|
||||
|
||||
let high_cutoff = 1e16_f32;
|
||||
assert_eq!("1e16", format!("{:?}", high_cutoff));
|
||||
assert_eq!("-1e16", format!("{:?}", -high_cutoff));
|
||||
assert!(!is_exponential(&format!("{:?}", high_cutoff * (1.0 - 2.0 * f32::EPSILON))));
|
||||
assert_eq!("-3.0", format!("{:?}", -3f32));
|
||||
assert_eq!("0.0001", format!("{:?}", 0.0001f32));
|
||||
assert_eq!("9e-5", format!("{:?}", 0.00009f32));
|
||||
assert_eq!("1234567.9", format!("{:.1?}", 1234567.89f32));
|
||||
assert_eq!("1234.6", format!("{:.1?}", 1234.56789f32));
|
||||
}
|
||||
|
||||
fn is_exponential(s: &str) -> bool {
|
||||
s.contains("e") || s.contains("E")
|
||||
}
|
||||
|
@ -47,6 +47,12 @@ fn unsync_once_cell_drop_empty() {
|
||||
drop(x);
|
||||
}
|
||||
|
||||
#[test]
|
||||
const fn once_cell_const() {
|
||||
let _once_cell: OnceCell<u32> = OnceCell::new();
|
||||
let _once_cell: OnceCell<u32> = OnceCell::from(32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone() {
|
||||
let s = OnceCell::new();
|
||||
|
@ -9,6 +9,7 @@
|
||||
#![feature(cfg_target_has_atomic)]
|
||||
#![feature(const_assume)]
|
||||
#![feature(const_cell_into_inner)]
|
||||
#![feature(const_convert)]
|
||||
#![feature(const_maybe_uninit_assume_init)]
|
||||
#![cfg_attr(bootstrap, feature(const_panic))]
|
||||
#![feature(const_ptr_read)]
|
||||
|
@ -214,6 +214,9 @@ fn nonzero_const() {
|
||||
|
||||
const ONE: Option<NonZeroU8> = NonZeroU8::new(1);
|
||||
assert!(ONE.is_some());
|
||||
|
||||
const FROM_NONZERO: u8 = u8::from(NONZERO);
|
||||
assert_eq!(FROM_NONZERO, 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -358,10 +358,17 @@ fn option_const() {
|
||||
// test that the methods of `Option` are usable in a const context
|
||||
|
||||
const OPTION: Option<usize> = Some(32);
|
||||
assert_eq!(OPTION, Some(32));
|
||||
|
||||
const OPTION_FROM: Option<usize> = Option::from(32);
|
||||
assert_eq!(OPTION_FROM, Some(32));
|
||||
|
||||
const REF: Option<&usize> = OPTION.as_ref();
|
||||
assert_eq!(REF, Some(&32));
|
||||
|
||||
const REF_FROM: Option<&usize> = Option::from(&OPTION);
|
||||
assert_eq!(REF_FROM, Some(&32));
|
||||
|
||||
const IS_SOME: bool = OPTION.is_some();
|
||||
assert!(IS_SOME);
|
||||
|
||||
@ -388,6 +395,14 @@ const fn option_const_mut() {
|
||||
None => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
let as_mut: Option<&mut usize> = Option::from(&mut option);
|
||||
match as_mut {
|
||||
Some(v) => *v = 42,
|
||||
None => unreachable!(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -25,7 +25,7 @@ pub macro panic_2015 {
|
||||
$crate::rt::panic_display(&$arg)
|
||||
}),
|
||||
($fmt:expr, $($arg:tt)+) => ({
|
||||
$crate::rt::begin_panic_fmt(&$crate::const_format_args!($fmt, $($arg)+))
|
||||
$crate::rt::panic_fmt($crate::const_format_args!($fmt, $($arg)+))
|
||||
}),
|
||||
}
|
||||
|
||||
|
@ -437,31 +437,9 @@ pub fn panicking() -> bool {
|
||||
!panic_count::count_is_zero()
|
||||
}
|
||||
|
||||
/// The entry point for panicking with a formatted message.
|
||||
///
|
||||
/// This is designed to reduce the amount of code required at the call
|
||||
/// site as much as possible (so that `panic!()` has as low an impact
|
||||
/// on (e.g.) the inlining of other functions as possible), by moving
|
||||
/// the actual formatting into this shared place.
|
||||
#[unstable(feature = "libstd_sys_internals", reason = "used by the panic! macro", issue = "none")]
|
||||
#[cold]
|
||||
// If panic_immediate_abort, inline the abort call,
|
||||
// otherwise avoid inlining because of it is cold path.
|
||||
#[cfg_attr(not(feature = "panic_immediate_abort"), track_caller)]
|
||||
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
|
||||
#[cfg_attr(feature = "panic_immediate_abort", inline)]
|
||||
#[cfg_attr(not(test), lang = "begin_panic_fmt")]
|
||||
pub fn begin_panic_fmt(msg: &fmt::Arguments<'_>) -> ! {
|
||||
if cfg!(feature = "panic_immediate_abort") {
|
||||
intrinsics::abort()
|
||||
}
|
||||
|
||||
let info = PanicInfo::internal_constructor(Some(msg), Location::caller());
|
||||
begin_panic_handler(&info)
|
||||
}
|
||||
|
||||
/// Entry point of panics from the libcore crate (`panic_impl` lang item).
|
||||
#[cfg_attr(not(test), panic_handler)]
|
||||
#[cfg(not(test))]
|
||||
#[panic_handler]
|
||||
pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
|
||||
struct PanicPayload<'a> {
|
||||
inner: &'a fmt::Arguments<'a>,
|
||||
|
@ -19,8 +19,8 @@
|
||||
use crate::ffi::CString;
|
||||
|
||||
// Re-export some of our utilities which are expected by other crates.
|
||||
pub use crate::panicking::{begin_panic, begin_panic_fmt, panic_count};
|
||||
pub use core::panicking::panic_display;
|
||||
pub use crate::panicking::{begin_panic, panic_count};
|
||||
pub use core::panicking::{panic_display, panic_fmt};
|
||||
|
||||
use crate::sync::Once;
|
||||
use crate::sys;
|
||||
|
@ -482,24 +482,26 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::
|
||||
+ name.as_str().len()
|
||||
+ generics_len;
|
||||
|
||||
wrap_item(w, "fn", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
w.reserve(header_len);
|
||||
write!(
|
||||
w,
|
||||
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
|
||||
{name}{generics}{decl}{notable_traits}{where_clause}",
|
||||
vis = vis,
|
||||
constness = constness,
|
||||
asyncness = asyncness,
|
||||
unsafety = unsafety,
|
||||
abi = abi,
|
||||
name = name,
|
||||
generics = f.generics.print(cx),
|
||||
where_clause = print_where_clause(&f.generics, cx, 0, true),
|
||||
decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
|
||||
notable_traits = notable_traits_decl(&f.decl, cx),
|
||||
);
|
||||
wrap_into_docblock(w, |w| {
|
||||
wrap_item(w, "fn", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
w.reserve(header_len);
|
||||
write!(
|
||||
w,
|
||||
"{vis}{constness}{asyncness}{unsafety}{abi}fn \
|
||||
{name}{generics}{decl}{notable_traits}{where_clause}",
|
||||
vis = vis,
|
||||
constness = constness,
|
||||
asyncness = asyncness,
|
||||
unsafety = unsafety,
|
||||
abi = abi,
|
||||
name = name,
|
||||
generics = f.generics.print(cx),
|
||||
where_clause = print_where_clause(&f.generics, cx, 0, true),
|
||||
decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
|
||||
notable_traits = notable_traits_decl(&f.decl, cx),
|
||||
);
|
||||
});
|
||||
});
|
||||
document(w, cx, it, None, HeadingOffset::H2)
|
||||
}
|
||||
@ -844,16 +846,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
|
||||
}
|
||||
|
||||
fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TraitAlias) {
|
||||
wrap_item(w, "trait-alias", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
write!(
|
||||
w,
|
||||
"trait {}{}{} = {};",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics.print(cx),
|
||||
print_where_clause(&t.generics, cx, 0, true),
|
||||
bounds(&t.bounds, true, cx)
|
||||
);
|
||||
wrap_into_docblock(w, |w| {
|
||||
wrap_item(w, "trait-alias", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
write!(
|
||||
w,
|
||||
"trait {}{}{} = {};",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics.print(cx),
|
||||
print_where_clause(&t.generics, cx, 0, true),
|
||||
bounds(&t.bounds, true, cx)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
document(w, cx, it, None, HeadingOffset::H2);
|
||||
@ -866,16 +870,18 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clea
|
||||
}
|
||||
|
||||
fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::OpaqueTy) {
|
||||
wrap_item(w, "opaque", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
write!(
|
||||
w,
|
||||
"type {}{}{where_clause} = impl {bounds};",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics.print(cx),
|
||||
where_clause = print_where_clause(&t.generics, cx, 0, true),
|
||||
bounds = bounds(&t.bounds, false, cx),
|
||||
);
|
||||
wrap_into_docblock(w, |w| {
|
||||
wrap_item(w, "opaque", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
write!(
|
||||
w,
|
||||
"type {}{}{where_clause} = impl {bounds};",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics.print(cx),
|
||||
where_clause = print_where_clause(&t.generics, cx, 0, true),
|
||||
bounds = bounds(&t.bounds, false, cx),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
document(w, cx, it, None, HeadingOffset::H2);
|
||||
@ -894,20 +900,37 @@ fn item_typedef(
|
||||
t: &clean::Typedef,
|
||||
is_associated: bool,
|
||||
) {
|
||||
wrap_item(w, "typedef", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
if !is_associated {
|
||||
write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
|
||||
}
|
||||
write!(
|
||||
w,
|
||||
"type {}{}{where_clause} = {type_};",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics.print(cx),
|
||||
where_clause = print_where_clause(&t.generics, cx, 0, true),
|
||||
type_ = t.type_.print(cx),
|
||||
);
|
||||
});
|
||||
fn write_content(
|
||||
w: &mut Buffer,
|
||||
cx: &Context<'_>,
|
||||
it: &clean::Item,
|
||||
t: &clean::Typedef,
|
||||
is_associated: bool,
|
||||
) {
|
||||
wrap_item(w, "typedef", |w| {
|
||||
render_attributes_in_pre(w, it, "");
|
||||
if !is_associated {
|
||||
write!(w, "{}", it.visibility.print_with_space(it.def_id, cx));
|
||||
}
|
||||
write!(
|
||||
w,
|
||||
"type {}{}{where_clause} = {type_};",
|
||||
it.name.as_ref().unwrap(),
|
||||
t.generics.print(cx),
|
||||
where_clause = print_where_clause(&t.generics, cx, 0, true),
|
||||
type_ = t.type_.print(cx),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// If this is an associated typedef, we don't want to wrap it into a docblock.
|
||||
if is_associated {
|
||||
write_content(w, cx, it, t, is_associated);
|
||||
} else {
|
||||
wrap_into_docblock(w, |w| {
|
||||
write_content(w, cx, it, t, is_associated);
|
||||
});
|
||||
}
|
||||
|
||||
document(w, cx, it, None, HeadingOffset::H2);
|
||||
|
||||
@ -1142,32 +1165,34 @@ fn item_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Mac
|
||||
}
|
||||
|
||||
fn item_proc_macro(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) {
|
||||
let name = it.name.as_ref().expect("proc-macros always have names");
|
||||
match m.kind {
|
||||
MacroKind::Bang => {
|
||||
wrap_item(w, "macro", |w| {
|
||||
write!(w, "{}!() {{ /* proc-macro */ }}", name);
|
||||
});
|
||||
}
|
||||
MacroKind::Attr => {
|
||||
wrap_item(w, "attr", |w| {
|
||||
write!(w, "#[{}]", name);
|
||||
});
|
||||
}
|
||||
MacroKind::Derive => {
|
||||
wrap_item(w, "derive", |w| {
|
||||
write!(w, "#[derive({})]", name);
|
||||
if !m.helpers.is_empty() {
|
||||
w.push_str("\n{\n");
|
||||
w.push_str(" // Attributes available to this derive:\n");
|
||||
for attr in &m.helpers {
|
||||
writeln!(w, " #[{}]", attr);
|
||||
wrap_into_docblock(w, |w| {
|
||||
let name = it.name.as_ref().expect("proc-macros always have names");
|
||||
match m.kind {
|
||||
MacroKind::Bang => {
|
||||
wrap_item(w, "macro", |w| {
|
||||
write!(w, "{}!() {{ /* proc-macro */ }}", name);
|
||||
});
|
||||
}
|
||||
MacroKind::Attr => {
|
||||
wrap_item(w, "attr", |w| {
|
||||
write!(w, "#[{}]", name);
|
||||
});
|
||||
}
|
||||
MacroKind::Derive => {
|
||||
wrap_item(w, "derive", |w| {
|
||||
write!(w, "#[derive({})]", name);
|
||||
if !m.helpers.is_empty() {
|
||||
w.push_str("\n{\n");
|
||||
w.push_str(" // Attributes available to this derive:\n");
|
||||
for attr in &m.helpers {
|
||||
writeln!(w, " #[{}]", attr);
|
||||
}
|
||||
w.push_str("}\n");
|
||||
}
|
||||
w.push_str("}\n");
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
document(w, cx, it, None, HeadingOffset::H2)
|
||||
}
|
||||
|
||||
@ -1177,38 +1202,40 @@ fn item_primitive(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
|
||||
}
|
||||
|
||||
fn item_constant(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, c: &clean::Constant) {
|
||||
wrap_item(w, "const", |w| {
|
||||
render_attributes_in_code(w, it);
|
||||
wrap_into_docblock(w, |w| {
|
||||
wrap_item(w, "const", |w| {
|
||||
render_attributes_in_code(w, it);
|
||||
|
||||
write!(
|
||||
w,
|
||||
"{vis}const {name}: {typ}",
|
||||
vis = it.visibility.print_with_space(it.def_id, cx),
|
||||
name = it.name.as_ref().unwrap(),
|
||||
typ = c.type_.print(cx),
|
||||
);
|
||||
write!(
|
||||
w,
|
||||
"{vis}const {name}: {typ}",
|
||||
vis = it.visibility.print_with_space(it.def_id, cx),
|
||||
name = it.name.as_ref().unwrap(),
|
||||
typ = c.type_.print(cx),
|
||||
);
|
||||
|
||||
let value = c.value(cx.tcx());
|
||||
let is_literal = c.is_literal(cx.tcx());
|
||||
let expr = c.expr(cx.tcx());
|
||||
if value.is_some() || is_literal {
|
||||
write!(w, " = {expr};", expr = Escape(&expr));
|
||||
} else {
|
||||
w.write_str(";");
|
||||
}
|
||||
let value = c.value(cx.tcx());
|
||||
let is_literal = c.is_literal(cx.tcx());
|
||||
let expr = c.expr(cx.tcx());
|
||||
if value.is_some() || is_literal {
|
||||
write!(w, " = {expr};", expr = Escape(&expr));
|
||||
} else {
|
||||
w.write_str(";");
|
||||
}
|
||||
|
||||
if !is_literal {
|
||||
if let Some(value) = &value {
|
||||
let value_lowercase = value.to_lowercase();
|
||||
let expr_lowercase = expr.to_lowercase();
|
||||
if !is_literal {
|
||||
if let Some(value) = &value {
|
||||
let value_lowercase = value.to_lowercase();
|
||||
let expr_lowercase = expr.to_lowercase();
|
||||
|
||||
if value_lowercase != expr_lowercase
|
||||
&& value_lowercase.trim_end_matches("i32") != expr_lowercase
|
||||
{
|
||||
write!(w, " // {value}", value = Escape(value));
|
||||
if value_lowercase != expr_lowercase
|
||||
&& value_lowercase.trim_end_matches("i32") != expr_lowercase
|
||||
{
|
||||
write!(w, " // {value}", value = Escape(value));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
document(w, cx, it, None, HeadingOffset::H2)
|
||||
@ -1268,30 +1295,34 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
|
||||
}
|
||||
|
||||
fn item_static(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::Static) {
|
||||
wrap_item(w, "static", |w| {
|
||||
render_attributes_in_code(w, it);
|
||||
write!(
|
||||
w,
|
||||
"{vis}static {mutability}{name}: {typ}",
|
||||
vis = it.visibility.print_with_space(it.def_id, cx),
|
||||
mutability = s.mutability.print_with_space(),
|
||||
name = it.name.as_ref().unwrap(),
|
||||
typ = s.type_.print(cx)
|
||||
);
|
||||
wrap_into_docblock(w, |w| {
|
||||
wrap_item(w, "static", |w| {
|
||||
render_attributes_in_code(w, it);
|
||||
write!(
|
||||
w,
|
||||
"{vis}static {mutability}{name}: {typ}",
|
||||
vis = it.visibility.print_with_space(it.def_id, cx),
|
||||
mutability = s.mutability.print_with_space(),
|
||||
name = it.name.as_ref().unwrap(),
|
||||
typ = s.type_.print(cx)
|
||||
);
|
||||
});
|
||||
});
|
||||
document(w, cx, it, None, HeadingOffset::H2)
|
||||
}
|
||||
|
||||
fn item_foreign_type(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item) {
|
||||
wrap_item(w, "foreigntype", |w| {
|
||||
w.write_str("extern {\n");
|
||||
render_attributes_in_code(w, it);
|
||||
write!(
|
||||
w,
|
||||
" {}type {};\n}}",
|
||||
it.visibility.print_with_space(it.def_id, cx),
|
||||
it.name.as_ref().unwrap(),
|
||||
);
|
||||
wrap_into_docblock(w, |w| {
|
||||
wrap_item(w, "foreigntype", |w| {
|
||||
w.write_str("extern {\n");
|
||||
render_attributes_in_code(w, it);
|
||||
write!(
|
||||
w,
|
||||
" {}type {};\n}}",
|
||||
it.visibility.print_with_space(it.def_id, cx),
|
||||
it.name.as_ref().unwrap(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
document(w, cx, it, None, HeadingOffset::H2);
|
||||
@ -1374,7 +1405,7 @@ fn wrap_into_docblock<F>(w: &mut Buffer, f: F)
|
||||
where
|
||||
F: FnOnce(&mut Buffer),
|
||||
{
|
||||
w.write_str("<div class=\"docblock type-decl\">");
|
||||
w.write_str("<div class=\"docblock item-decl\">");
|
||||
f(w);
|
||||
w.write_str("</div>")
|
||||
}
|
||||
|
@ -129,9 +129,14 @@ h3 {
|
||||
}
|
||||
h1, h2, h3, h4, h5, h6 {
|
||||
font-weight: 500;
|
||||
}
|
||||
h1, h2, h3, h4 {
|
||||
margin: 20px 0 15px 0;
|
||||
padding-bottom: 6px;
|
||||
}
|
||||
h5, h6 {
|
||||
margin: 15px 0 5px 0;
|
||||
}
|
||||
h1.fqn {
|
||||
display: flex;
|
||||
border-bottom: 1px dashed;
|
||||
@ -254,7 +259,10 @@ code, pre, a.test-arrow, .code-header {
|
||||
pre {
|
||||
padding: 14px;
|
||||
}
|
||||
.type-decl pre {
|
||||
.docblock.item-decl {
|
||||
margin-left: 0;
|
||||
}
|
||||
.item-decl pre {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
@ -502,14 +510,12 @@ nav.sub {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5, .docblock h6 {
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
.top-doc .docblock h2 { font-size: 1.3em; }
|
||||
.top-doc .docblock h3 { font-size: 1.15em; }
|
||||
.top-doc .docblock h4,
|
||||
.top-doc .docblock h5,
|
||||
.top-doc .docblock h5 {
|
||||
font-size: 1.1em;
|
||||
}
|
||||
.top-doc .docblock h6 {
|
||||
font-size: 1em;
|
||||
}
|
||||
@ -550,6 +556,7 @@ nav.sub {
|
||||
flex-grow: 1;
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.in-band > code, .in-band > .code-header {
|
||||
|
@ -220,7 +220,7 @@ body.source .example-wrap pre.rust a {
|
||||
background: #333;
|
||||
}
|
||||
|
||||
.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
|
||||
.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow),
|
||||
.docblock-short a:not(.srclink):not(.test-arrow), .item-info a,
|
||||
#help a {
|
||||
color: #39AFD7;
|
||||
|
@ -181,7 +181,7 @@ body.source .example-wrap pre.rust a {
|
||||
background: #333;
|
||||
}
|
||||
|
||||
.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
|
||||
.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow),
|
||||
.docblock-short a:not(.srclink):not(.test-arrow), .item-info a,
|
||||
#help a {
|
||||
color: #D2991D;
|
||||
|
@ -176,7 +176,7 @@ body.source .example-wrap pre.rust a {
|
||||
background: #eee;
|
||||
}
|
||||
|
||||
.docblock:not(.type-decl) a:not(.srclink):not(.test-arrow),
|
||||
.docblock:not(.item-decl) a:not(.srclink):not(.test-arrow),
|
||||
.docblock-short a:not(.srclink):not(.test-arrow), .item-info a,
|
||||
#help a {
|
||||
color: #3873AD;
|
||||
|
@ -1,4 +1,4 @@
|
||||
goto: file://|DOC_PATH|/test_docs/index.html
|
||||
assert: ("#functions")
|
||||
goto: ./struct.Foo.html
|
||||
assert: ("div.type-decl")
|
||||
assert: ("div.item-decl")
|
||||
|
6
src/test/rustdoc-gui/check-code-blocks-margin.goml
Normal file
6
src/test/rustdoc-gui/check-code-blocks-margin.goml
Normal file
@ -0,0 +1,6 @@
|
||||
// This test ensures that the docblock elements have the appropriate left margin.
|
||||
goto: file://|DOC_PATH|/test_docs/fn.foo.html
|
||||
// The top docblock elements shouldn't have left margin...
|
||||
assert-css: ("#main .docblock.item-decl", {"margin-left": "0px"})
|
||||
// ... but all the others should!
|
||||
assert-css: ("#main .docblock:not(.item-decl)", {"margin-left": "24px"})
|
@ -1,6 +1,6 @@
|
||||
goto: file://|DOC_PATH|/lib2/struct.Foo.html
|
||||
// This test checks that the font weight is correctly applied.
|
||||
assert-css: ("//*[@class='docblock type-decl']//a[text()='Alias']", {"font-weight": "400"})
|
||||
assert-css: ("//*[@class='docblock item-decl']//a[text()='Alias']", {"font-weight": "400"})
|
||||
assert-css: ("//*[@class='structfield small-section-header']//a[text()='Alias']", {"font-weight": "400"})
|
||||
assert-css: ("#method\.a_method > .code-header", {"font-weight": "600"})
|
||||
assert-css: ("#associatedtype\.X > .code-header", {"font-weight": "600"})
|
||||
@ -16,7 +16,7 @@ goto: file://|DOC_PATH|/lib2/trait.Trait.html
|
||||
|
||||
// This is a complex selector, so here's how it works:
|
||||
//
|
||||
// * //*[@class='docblock type-decl'] — selects element of any tag with classes docblock and type-decl
|
||||
// * //*[@class='docblock item-decl'] — selects element of any tag with classes docblock and item-decl
|
||||
// * /pre[@class='rust trait'] — selects immediate child with tag pre and classes rust and trait
|
||||
// * /code — selects immediate child with tag code
|
||||
// * /a[@class='constant'] — selects immediate child with tag a and class constant
|
||||
@ -25,8 +25,8 @@ goto: file://|DOC_PATH|/lib2/trait.Trait.html
|
||||
//
|
||||
// This uses '/parent::*' as a proxy for the style of the text node.
|
||||
// We can't just select the '<a>' because intermediate tags could be added.
|
||||
assert-count: ("//*[@class='docblock type-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", 1)
|
||||
assert-css: ("//*[@class='docblock type-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", {"font-weight": "400"})
|
||||
assert-count: ("//*[@class='docblock item-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", 1)
|
||||
assert-css: ("//*[@class='docblock item-decl']/pre[@class='rust trait']/code/a[@class='constant']//text()/parent::*", {"font-weight": "400"})
|
||||
|
||||
assert-count: (".methods .type", 1)
|
||||
assert-css: (".methods .type", {"font-weight": "600"})
|
||||
|
@ -84,3 +84,20 @@ pub mod summary_table {
|
||||
/// | content | content |
|
||||
pub struct Foo;
|
||||
}
|
||||
|
||||
pub mod too_long {
|
||||
pub type ReallyLongTypeNameLongLongLong = Option<unsafe extern "C" fn(a: *const u8, b: *const u8) -> *const u8>;
|
||||
|
||||
pub const ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong: u32 = 0;
|
||||
|
||||
pub struct SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName {
|
||||
pub a: u32,
|
||||
}
|
||||
|
||||
impl SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName {
|
||||
/// ```
|
||||
/// let x = SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName { a: 0 };
|
||||
/// ```
|
||||
pub fn foo(&self) {}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,25 @@
|
||||
// This test ensures that the type declaration content overflow is handled inside the <pre> directly.
|
||||
// This test ensures that the items declaration content overflow is handled inside the <pre> directly.
|
||||
goto: file://|DOC_PATH|/lib2/long_trait/trait.ALongNameBecauseItHelpsTestingTheCurrentProblem.html
|
||||
// We set a fixed size so there is no chance of "random" resize.
|
||||
size: (1100, 800)
|
||||
// Logically, the <body> scroll width should be the width of the window.
|
||||
assert-property: ("body", {"scrollWidth": "1100"})
|
||||
// However, since there is overflow in the type declaration, its scroll width is bigger.
|
||||
assert-property: (".type-decl pre", {"scrollWidth": "1324"})
|
||||
assert-property: (".item-decl pre", {"scrollWidth": "1324"})
|
||||
|
||||
// We now make the same check on type declaration...
|
||||
goto: file://|DOC_PATH|/lib2/too_long/type.ReallyLongTypeNameLongLongLong.html
|
||||
assert-property: ("body", {"scrollWidth": "1100"})
|
||||
// We now check that the section width hasn't grown because of it.
|
||||
assert-property: ("#main", {"scrollWidth": "840"})
|
||||
// And now checking that it has scrollable content.
|
||||
assert-property: (".item-decl pre", {"scrollWidth": "1103"})
|
||||
|
||||
// ... and constant.
|
||||
// On a sidenote, it also checks that the (very) long title isn't changing the docblock width.
|
||||
goto: file://|DOC_PATH|/lib2/too_long/constant.ReallyLongTypeNameLongLongLongConstBecauseWhyNotAConstRightGigaGigaSupraLong.html
|
||||
assert-property: ("body", {"scrollWidth": "1100"})
|
||||
// We now check that the section width hasn't grown because of it.
|
||||
assert-property: ("#main", {"scrollWidth": "840"})
|
||||
// And now checking that it has scrollable content.
|
||||
assert-property: (".item-decl pre", {"scrollWidth": "950"})
|
||||
|
@ -8,6 +8,6 @@ pub extern "C" fn f() {}
|
||||
#[export_name = "bar"]
|
||||
pub extern "C" fn g() {}
|
||||
|
||||
// @has foo/struct.Repr.html '//*[@class="docblock type-decl"]' '#[repr(C, align(8))]'
|
||||
// @has foo/struct.Repr.html '//*[@class="docblock item-decl"]' '#[repr(C, align(8))]'
|
||||
#[repr(C, align(8))]
|
||||
pub struct Repr;
|
||||
|
@ -5,25 +5,25 @@
|
||||
|
||||
extern crate reexports;
|
||||
|
||||
// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
|
||||
// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
|
||||
pub use reexports::addr_of;
|
||||
// @has 'foo/macro.addr_of_crate.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
|
||||
// @has 'foo/macro.addr_of_crate.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_crate($place : expr) {'
|
||||
pub(crate) use reexports::addr_of_crate;
|
||||
// @has 'foo/macro.addr_of_self.html' '//*[@class="docblock type-decl"]' 'pub(crate) macro addr_of_self($place : expr) {'
|
||||
// @has 'foo/macro.addr_of_self.html' '//*[@class="docblock item-decl"]' 'pub(crate) macro addr_of_self($place : expr) {'
|
||||
pub(self) use reexports::addr_of_self;
|
||||
|
||||
// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
|
||||
// @has 'foo/struct.Foo.html' '//*[@class="docblock item-decl"]' 'pub struct Foo;'
|
||||
pub use reexports::Foo;
|
||||
// @has 'foo/struct.FooCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooCrate;'
|
||||
// @has 'foo/struct.FooCrate.html' '//*[@class="docblock item-decl"]' 'pub(crate) struct FooCrate;'
|
||||
pub(crate) use reexports::FooCrate;
|
||||
// @has 'foo/struct.FooSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) struct FooSelf;'
|
||||
// @has 'foo/struct.FooSelf.html' '//*[@class="docblock item-decl"]' 'pub(crate) struct FooSelf;'
|
||||
pub(self) use reexports::FooSelf;
|
||||
|
||||
// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
|
||||
// @has 'foo/enum.Bar.html' '//*[@class="docblock item-decl"]' 'pub enum Bar {'
|
||||
pub use reexports::Bar;
|
||||
// @has 'foo/enum.BarCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarCrate {'
|
||||
// @has 'foo/enum.BarCrate.html' '//*[@class="docblock item-decl"]' 'pub(crate) enum BarCrate {'
|
||||
pub(crate) use reexports::BarCrate;
|
||||
// @has 'foo/enum.BarSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) enum BarSelf {'
|
||||
// @has 'foo/enum.BarSelf.html' '//*[@class="docblock item-decl"]' 'pub(crate) enum BarSelf {'
|
||||
pub(self) use reexports::BarSelf;
|
||||
|
||||
// @has 'foo/fn.foo.html' '//*[@class="rust fn"]' 'pub fn foo()'
|
||||
@ -40,11 +40,11 @@ pub(crate) use reexports::TypeCrate;
|
||||
// @has 'foo/type.TypeSelf.html' '//*[@class="rust typedef"]' 'pub(crate) type TypeSelf ='
|
||||
pub(self) use reexports::TypeSelf;
|
||||
|
||||
// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
|
||||
// @has 'foo/union.Union.html' '//*[@class="docblock item-decl"]' 'pub union Union {'
|
||||
pub use reexports::Union;
|
||||
// @has 'foo/union.UnionCrate.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionCrate {'
|
||||
// @has 'foo/union.UnionCrate.html' '//*[@class="docblock item-decl"]' 'pub(crate) union UnionCrate {'
|
||||
pub(crate) use reexports::UnionCrate;
|
||||
// @has 'foo/union.UnionSelf.html' '//*[@class="docblock type-decl"]' 'pub(crate) union UnionSelf {'
|
||||
// @has 'foo/union.UnionSelf.html' '//*[@class="docblock item-decl"]' 'pub(crate) union UnionSelf {'
|
||||
pub(self) use reexports::UnionSelf;
|
||||
|
||||
pub mod foo {
|
||||
|
@ -4,21 +4,21 @@
|
||||
|
||||
extern crate reexports;
|
||||
|
||||
// @has 'foo/macro.addr_of.html' '//*[@class="docblock type-decl"]' 'pub macro addr_of($place : expr) {'
|
||||
// @has 'foo/macro.addr_of.html' '//*[@class="docblock item-decl"]' 'pub macro addr_of($place : expr) {'
|
||||
pub use reexports::addr_of;
|
||||
// @!has 'foo/macro.addr_of_crate.html'
|
||||
pub(crate) use reexports::addr_of_crate;
|
||||
// @!has 'foo/macro.addr_of_self.html'
|
||||
pub(self) use reexports::addr_of_self;
|
||||
|
||||
// @has 'foo/struct.Foo.html' '//*[@class="docblock type-decl"]' 'pub struct Foo;'
|
||||
// @has 'foo/struct.Foo.html' '//*[@class="docblock item-decl"]' 'pub struct Foo;'
|
||||
pub use reexports::Foo;
|
||||
// @!has 'foo/struct.FooCrate.html'
|
||||
pub(crate) use reexports::FooCrate;
|
||||
// @!has 'foo/struct.FooSelf.html'
|
||||
pub(self) use reexports::FooSelf;
|
||||
|
||||
// @has 'foo/enum.Bar.html' '//*[@class="docblock type-decl"]' 'pub enum Bar {'
|
||||
// @has 'foo/enum.Bar.html' '//*[@class="docblock item-decl"]' 'pub enum Bar {'
|
||||
pub use reexports::Bar;
|
||||
// @!has 'foo/enum.BarCrate.html'
|
||||
pub(crate) use reexports::BarCrate;
|
||||
@ -39,7 +39,7 @@ pub(crate) use reexports::TypeCrate;
|
||||
// @!has 'foo/type.TypeSelf.html'
|
||||
pub(self) use reexports::TypeSelf;
|
||||
|
||||
// @has 'foo/union.Union.html' '//*[@class="docblock type-decl"]' 'pub union Union {'
|
||||
// @has 'foo/union.Union.html' '//*[@class="docblock item-decl"]' 'pub union Union {'
|
||||
pub use reexports::Union;
|
||||
// @!has 'foo/union.UnionCrate.html'
|
||||
pub(crate) use reexports::UnionCrate;
|
||||
|
@ -55,7 +55,7 @@ pub union Union {
|
||||
|
||||
// @has 'toggle_item_contents/struct.PrivStruct.html'
|
||||
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 0
|
||||
// @has - '//div[@class="docblock type-decl"]' 'fields omitted'
|
||||
// @has - '//div[@class="docblock item-decl"]' 'fields omitted'
|
||||
pub struct PrivStruct {
|
||||
a: usize,
|
||||
b: usize,
|
||||
|
@ -13,11 +13,14 @@ use std::fmt::Debug;
|
||||
// @has foo/index.html '//a[@class="traitalias"]' 'Alias2'
|
||||
// @has foo/index.html '//a[@class="traitalias"]' 'Foo'
|
||||
|
||||
// @has foo/traitalias.CopyAlias.html '//section[@id="main"]/pre' 'trait CopyAlias = Copy;'
|
||||
// @has foo/traitalias.CopyAlias.html
|
||||
// @has - '//section[@id="main"]/div[@class="docblock item-decl"]/pre' 'trait CopyAlias = Copy;'
|
||||
pub trait CopyAlias = Copy;
|
||||
// @has foo/traitalias.Alias2.html '//section[@id="main"]/pre' 'trait Alias2 = Copy + Debug;'
|
||||
// @has foo/traitalias.Alias2.html
|
||||
// @has - '//section[@id="main"]/div[@class="docblock item-decl"]/pre' 'trait Alias2 = Copy + Debug;'
|
||||
pub trait Alias2 = Copy + Debug;
|
||||
// @has foo/traitalias.Foo.html '//section[@id="main"]/pre' 'trait Foo<T> = Into<T> + Debug;'
|
||||
// @has foo/traitalias.Foo.html
|
||||
// @has - '//section[@id="main"]/div[@class="docblock item-decl"]/pre' 'trait Foo<T> = Into<T> + Debug;'
|
||||
pub trait Foo<T> = Into<T> + Debug;
|
||||
// @has foo/fn.bar.html '//a[@href="traitalias.Alias2.html"]' 'Alias2'
|
||||
pub fn bar<T>() where T: Alias2 {}
|
||||
|
@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
|
||||
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
||||
|
|
||||
LL | fn hash<H: Hasher>(&self, state: &mut H);
|
||||
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
|
||||
| ^ required by this bound in `std::hash::Hash::hash`
|
||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
|
||||
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
||||
|
|
||||
LL | fn hash<H: Hasher>(&self, state: &mut H);
|
||||
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
|
||||
| ^ required by this bound in `std::hash::Hash::hash`
|
||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
|
||||
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
||||
|
|
||||
LL | fn hash<H: Hasher>(&self, state: &mut H);
|
||||
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
|
||||
| ^ required by this bound in `std::hash::Hash::hash`
|
||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -11,7 +11,7 @@ note: required by a bound in `std::hash::Hash::hash`
|
||||
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
||||
|
|
||||
LL | fn hash<H: Hasher>(&self, state: &mut H);
|
||||
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
|
||||
| ^ required by this bound in `std::hash::Hash::hash`
|
||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,19 +1,3 @@
|
||||
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
||||
--> $DIR/issue-74816.rs:9:5
|
||||
|
|
||||
LL | type Associated: Trait1 = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
note: required by a bound in `Trait2::Associated`
|
||||
--> $DIR/issue-74816.rs:9:5
|
||||
|
|
||||
LL | type Associated: Trait1 = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | trait Trait2: Sized {
|
||||
| +++++++
|
||||
|
||||
error[E0277]: the trait bound `Self: Trait1` is not satisfied
|
||||
--> $DIR/issue-74816.rs:9:5
|
||||
|
|
||||
@ -30,6 +14,22 @@ help: consider further restricting `Self`
|
||||
LL | trait Trait2: Trait1 {
|
||||
| ++++++++
|
||||
|
||||
error[E0277]: the size for values of type `Self` cannot be known at compilation time
|
||||
--> $DIR/issue-74816.rs:9:5
|
||||
|
|
||||
LL | type Associated: Trait1 = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
||||
|
|
||||
note: required by a bound in `Trait2::Associated`
|
||||
--> $DIR/issue-74816.rs:9:5
|
||||
|
|
||||
LL | type Associated: Trait1 = Self;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `Trait2::Associated`
|
||||
help: consider further restricting `Self`
|
||||
|
|
||||
LL | trait Trait2: Sized {
|
||||
| +++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
@ -20,13 +20,13 @@ LL | for<'a> T: 'a,
|
||||
| ^^
|
||||
|
||||
error[E0311]: the parameter type `T` may not live long enough
|
||||
--> $DIR/issue-86483.rs:9:19
|
||||
--> $DIR/issue-86483.rs:9:5
|
||||
|
|
||||
LL | pub trait IceIce<T>
|
||||
| - help: consider adding an explicit lifetime bound...: `T: 'a`
|
||||
...
|
||||
LL | type Ice<'v>: IntoIterator<Item = &'v T>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ...so that the type `T` will meet its required lifetime bounds...
|
||||
|
|
||||
note: ...that is required by this bound
|
||||
--> $DIR/issue-86483.rs:7:16
|
||||
|
@ -6,10 +6,10 @@ LL | impl Tsized for () {}
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `[()]`
|
||||
note: required by a bound in `Tsized`
|
||||
--> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:17
|
||||
--> $DIR/issue-61631-default-type-param-can-reference-self-in-trait.rs:17:14
|
||||
|
|
||||
LL | trait Tsized<P: Sized = [Self]> {}
|
||||
| ^^^^^ required by this bound in `Tsized`
|
||||
| ^ required by this bound in `Tsized`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -1,21 +1,11 @@
|
||||
error[E0283]: type annotations needed
|
||||
error[E0282]: type annotations needed
|
||||
--> $DIR/issue-16966.rs:2:5
|
||||
|
|
||||
LL | panic!(std::default::Default::default());
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `M` declared on the function `begin_panic`
|
||||
|
|
||||
= note: cannot satisfy `_: Any`
|
||||
note: required by a bound in `begin_panic`
|
||||
--> $SRC_DIR/std/src/panicking.rs:LL:COL
|
||||
|
|
||||
LL | pub fn begin_panic<M: Any + Send>(msg: M) -> ! {
|
||||
| ^^^ required by this bound in `begin_panic`
|
||||
= note: this error originates in the macro `$crate::panic::panic_2015` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
help: consider specifying the type argument in the function call
|
||||
|
|
||||
LL | $crate::rt::begin_panic::<M>($msg)
|
||||
| +++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0283`.
|
||||
For more information about this error, try `rustc --explain E0282`.
|
||||
|
@ -10,7 +10,7 @@ note: required by a bound in `std::hash::Hash::hash`
|
||||
--> $SRC_DIR/core/src/hash/mod.rs:LL:COL
|
||||
|
|
||||
LL | fn hash<H: Hasher>(&self, state: &mut H);
|
||||
| ^^^^^^ required by this bound in `std::hash::Hash::hash`
|
||||
| ^ required by this bound in `std::hash::Hash::hash`
|
||||
= note: this error originates in the derive macro `Hash` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -1,4 +1,4 @@
|
||||
error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Next`
|
||||
error[E0275]: overflow evaluating the requirement `<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
|
||||
--> $DIR/issue-23122-2.rs:9:17
|
||||
|
|
||||
LL | type Next = <GetNext<T::Next> as Next>::Next;
|
||||
|
@ -12,10 +12,10 @@ LL | const ARR_LEN: usize = Tt::const_val::<[i8; 123]>();
|
||||
|
|
||||
= note: cannot satisfy `_: Tt`
|
||||
note: required by a bound in `Tt::const_val`
|
||||
--> $DIR/issue-54954.rs:5:27
|
||||
--> $DIR/issue-54954.rs:5:24
|
||||
|
|
||||
LL | const fn const_val<T: Sized>() -> usize {
|
||||
| ^^^^^ required by this bound in `Tt::const_val`
|
||||
| ^ required by this bound in `Tt::const_val`
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -20,11 +20,11 @@ error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||
LL | T::c::<T>();
|
||||
| ^^^^^^^^^ the trait `Bar` is not implemented for `T`
|
||||
|
|
||||
note: required by a bound in `Foo::c`
|
||||
--> $DIR/trait-where-clause.rs:9:10
|
||||
note: required by `Foo::c`
|
||||
--> $DIR/trait-where-clause.rs:9:5
|
||||
|
|
||||
LL | fn c<T: ~const Bar>();
|
||||
| ^ required by this bound in `Foo::c`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | const fn test1<T: ~const Foo + Bar + Bar>() {
|
||||
@ -52,11 +52,11 @@ error[E0277]: the trait bound `T: Bar` is not satisfied
|
||||
LL | T::c::<T>();
|
||||
| ^^^^^^^^^ the trait `Bar` is not implemented for `T`
|
||||
|
|
||||
note: required by a bound in `Foo::c`
|
||||
--> $DIR/trait-where-clause.rs:9:10
|
||||
note: required by `Foo::c`
|
||||
--> $DIR/trait-where-clause.rs:9:5
|
||||
|
|
||||
LL | fn c<T: ~const Bar>();
|
||||
| ^ required by this bound in `Foo::c`
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider further restricting this bound
|
||||
|
|
||||
LL | fn test3<T: Foo + Bar>() {
|
||||
|
@ -49,10 +49,10 @@ LL | f_sized(*ref_cl);
|
||||
|
|
||||
= help: the trait `Sized` is not implemented for `dyn Fn()`
|
||||
note: required by a bound in `f_sized`
|
||||
--> $DIR/issue-84973-blacklist.rs:9:15
|
||||
--> $DIR/issue-84973-blacklist.rs:9:12
|
||||
|
|
||||
LL | fn f_sized<T: Sized>(t: T) {}
|
||||
| ^^^^^ required by this bound in `f_sized`
|
||||
| ^ required by this bound in `f_sized`
|
||||
|
||||
error[E0277]: `Rc<{integer}>` cannot be sent between threads safely
|
||||
--> $DIR/issue-84973-blacklist.rs:27:12
|
||||
|
@ -1,23 +1,3 @@
|
||||
error[E0277]: `[i32]` is not an iterator
|
||||
--> $DIR/slice-issue-87994.rs:3:12
|
||||
|
|
||||
LL | for _ in v[1..] {
|
||||
| ^^^^^^ expected an implementor of trait `IntoIterator`
|
||||
|
|
||||
= note: the trait bound `[i32]: IntoIterator` is not satisfied
|
||||
= note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
|
||||
note: required by `into_iter`
|
||||
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||
|
|
||||
LL | fn into_iter(self) -> Self::IntoIter;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | for _ in &v[1..] {
|
||||
| +
|
||||
LL | for _ in &mut v[1..] {
|
||||
| ++++
|
||||
|
||||
error[E0277]: the size for values of type `[i32]` cannot be known at compilation time
|
||||
--> $DIR/slice-issue-87994.rs:3:12
|
||||
|
|
||||
@ -38,7 +18,27 @@ LL | for _ in &v[1..] {
|
||||
LL | for _ in &mut v[1..] {
|
||||
| ++++
|
||||
|
||||
error[E0277]: `[K]` is not an iterator
|
||||
error[E0277]: `[i32]` is not an iterator
|
||||
--> $DIR/slice-issue-87994.rs:3:12
|
||||
|
|
||||
LL | for _ in v[1..] {
|
||||
| ^^^^^^ expected an implementor of trait `IntoIterator`
|
||||
|
|
||||
= note: the trait bound `[i32]: IntoIterator` is not satisfied
|
||||
= note: required because of the requirements on the impl of `IntoIterator` for `[i32]`
|
||||
note: required by `into_iter`
|
||||
--> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
|
||||
|
|
||||
LL | fn into_iter(self) -> Self::IntoIter;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
help: consider borrowing here
|
||||
|
|
||||
LL | for _ in &v[1..] {
|
||||
| +
|
||||
LL | for _ in &mut v[1..] {
|
||||
| ++++
|
||||
|
||||
error[E0277]: the size for values of type `[K]` cannot be known at compilation time
|
||||
--> $DIR/slice-issue-87994.rs:11:13
|
||||
|
|
||||
LL | for i2 in v2[1..] {
|
||||
@ -58,7 +58,7 @@ LL | for i2 in &v2[1..] {
|
||||
LL | for i2 in &mut v2[1..] {
|
||||
| ++++
|
||||
|
||||
error[E0277]: the size for values of type `[K]` cannot be known at compilation time
|
||||
error[E0277]: `[K]` is not an iterator
|
||||
--> $DIR/slice-issue-87994.rs:11:13
|
||||
|
|
||||
LL | for i2 in v2[1..] {
|
||||
|
@ -5,7 +5,7 @@ use std::fmt::Debug;
|
||||
fn main() {}
|
||||
|
||||
type Two<A, B> = impl Debug;
|
||||
//~^ ERROR the trait bound `A: Foo` is not satisfied
|
||||
//~^ ERROR the trait bound `A: Foo` is not satisfied in `(A, B, <A as Foo>::Bar)`
|
||||
//~| ERROR `A` doesn't implement `Debug`
|
||||
//~| ERROR `B` doesn't implement `Debug`
|
||||
|
||||
|
@ -10,6 +10,18 @@ note: previous use here
|
||||
LL | fn two<T: Debug + Foo, U: Debug>(t: T, u: U) -> Two<T, U> {
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error[E0277]: the trait bound `A: Foo` is not satisfied in `(A, B, <A as Foo>::Bar)`
|
||||
--> $DIR/generic_duplicate_param_use9.rs:7:18
|
||||
|
|
||||
LL | type Two<A, B> = impl Debug;
|
||||
| ^^^^^^^^^^ within `(A, B, <A as Foo>::Bar)`, the trait `Foo` is not implemented for `A`
|
||||
|
|
||||
= note: required because it appears within the type `(A, B, <A as Foo>::Bar)`
|
||||
help: consider restricting type parameter `A`
|
||||
|
|
||||
LL | type Two<A: Foo, B> = impl Debug;
|
||||
| +++++
|
||||
|
||||
error[E0277]: `A` doesn't implement `Debug`
|
||||
--> $DIR/generic_duplicate_param_use9.rs:7:18
|
||||
|
|
||||
@ -34,18 +46,6 @@ help: consider restricting type parameter `B`
|
||||
LL | type Two<A, B: std::fmt::Debug> = impl Debug;
|
||||
| +++++++++++++++++
|
||||
|
||||
error[E0277]: the trait bound `A: Foo` is not satisfied
|
||||
--> $DIR/generic_duplicate_param_use9.rs:7:18
|
||||
|
|
||||
LL | type Two<A, B> = impl Debug;
|
||||
| ^^^^^^^^^^ the trait `Foo` is not implemented for `A`
|
||||
|
|
||||
= note: required because of the requirements on the impl of `Debug` for `(A, B, <A as Foo>::Bar)`
|
||||
help: consider restricting type parameter `A`
|
||||
|
|
||||
LL | type Two<A: Foo, B> = impl Debug;
|
||||
| +++++
|
||||
|
||||
error: aborting due to 4 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0277`.
|
||||
|
18
src/test/ui/typeck/issue-89935.rs
Normal file
18
src/test/ui/typeck/issue-89935.rs
Normal file
@ -0,0 +1,18 @@
|
||||
// check-pass
|
||||
|
||||
trait Foo: Baz {}
|
||||
trait Bar {}
|
||||
trait Baz: Bar {
|
||||
fn bar(&self);
|
||||
}
|
||||
|
||||
impl<T: Foo> Bar for T {}
|
||||
impl<T: Foo> Baz for T {
|
||||
fn bar(&self) {}
|
||||
}
|
||||
|
||||
fn accept_foo(x: Box<dyn Foo>) {
|
||||
x.bar();
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -19,10 +19,10 @@ LL | | >(Unique<T>, A);
|
||||
| |________________- doesn't satisfy `Box<dyn Foo>: Clone`
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`dyn Foo: Clone`
|
||||
which is required by `Box<dyn Foo>: Clone`
|
||||
`dyn Foo: Sized`
|
||||
which is required by `Box<dyn Foo>: Clone`
|
||||
`dyn Foo: Clone`
|
||||
which is required by `Box<dyn Foo>: Clone`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,10 +7,10 @@ LL | fn foo<T: ?Sized>() { bar::<T>() }
|
||||
| this type parameter needs to be `std::marker::Sized`
|
||||
|
|
||||
note: required by a bound in `bar`
|
||||
--> $DIR/unsized-bare-typaram.rs:1:11
|
||||
--> $DIR/unsized-bare-typaram.rs:1:8
|
||||
|
|
||||
LL | fn bar<T: Sized>() { }
|
||||
| ^^^^^ required by this bound in `bar`
|
||||
| ^ required by this bound in `bar`
|
||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||
|
|
||||
LL - fn foo<T: ?Sized>() { bar::<T>() }
|
||||
|
@ -38,10 +38,10 @@ note: required because it appears within the type `Bar<T>`
|
||||
LL | struct Bar<T: ?Sized> { data: T }
|
||||
| ^^^
|
||||
note: required by a bound in `is_sized`
|
||||
--> $DIR/unsized-struct.rs:1:15
|
||||
--> $DIR/unsized-struct.rs:1:13
|
||||
|
|
||||
LL | fn is_sized<T:Sized>() { }
|
||||
| ^^^^^ required by this bound in `is_sized`
|
||||
| ^ required by this bound in `is_sized`
|
||||
help: consider removing the `?Sized` bound to make the type parameter `Sized`
|
||||
|
|
||||
LL - fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
|
||||
|
@ -619,7 +619,6 @@ impl PanicExpn<'tcx> {
|
||||
if let Some(init) = block.expr;
|
||||
if let ExprKind::Call(_, [format_args]) = init.kind;
|
||||
let expn_data = expr.span.ctxt().outer_expn_data();
|
||||
if let ExprKind::AddrOf(_, _, format_args) = format_args.kind;
|
||||
if let Some(format_args) = FormatArgsExpn::parse(format_args);
|
||||
then {
|
||||
Some(PanicExpn {
|
||||
|
@ -1646,7 +1646,6 @@ pub fn match_panic_def_id(cx: &LateContext<'_>, did: DefId) -> bool {
|
||||
did,
|
||||
&[
|
||||
&paths::BEGIN_PANIC,
|
||||
&paths::BEGIN_PANIC_FMT,
|
||||
&paths::PANIC_ANY,
|
||||
&paths::PANICKING_PANIC,
|
||||
&paths::PANICKING_PANIC_FMT,
|
||||
|
@ -20,7 +20,6 @@ pub const ARC_PTR_EQ: [&str; 4] = ["alloc", "sync", "Arc", "ptr_eq"];
|
||||
pub const ASMUT_TRAIT: [&str; 3] = ["core", "convert", "AsMut"];
|
||||
pub const ASREF_TRAIT: [&str; 3] = ["core", "convert", "AsRef"];
|
||||
pub(super) const BEGIN_PANIC: [&str; 3] = ["std", "panicking", "begin_panic"];
|
||||
pub(super) const BEGIN_PANIC_FMT: [&str; 3] = ["std", "panicking", "begin_panic_fmt"];
|
||||
/// Preferably use the diagnostic item `sym::Borrow` where possible
|
||||
pub const BORROW_TRAIT: [&str; 3] = ["core", "borrow", "Borrow"];
|
||||
pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];
|
||||
|
Loading…
Reference in New Issue
Block a user