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:
bors 2021-10-19 22:14:21 +00:00
commit 42983a28ab
82 changed files with 676 additions and 406 deletions

View File

@ -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",

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -355,7 +355,6 @@ symbols! {
await_macro,
bang,
begin_panic,
begin_panic_fmt,
bench,
bin,
bind_by_move_pattern_guards,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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"})

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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