Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 0dd7e10

Browse files
committedMay 9, 2022
Auto merge of rust-lang#96877 - matthiaskrgr:rollup-evlh6ot, r=matthiaskrgr
Rollup of 6 pull requests Successful merges: - rust-lang#95483 (Improve floating point documentation) - rust-lang#96008 (Warn on unused `#[doc(hidden)]` attributes on trait impl items) - rust-lang#96841 (Revert "Implement [OsStr]::join", which was merged without FCP.) - rust-lang#96844 (Actually fix ICE from rust-lang#96583) - rust-lang#96854 (Some subst cleanup) - rust-lang#96858 (Remove unused param from search.js::checkPath) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0e345b7 + 5972222 commit 0dd7e10

File tree

37 files changed

+472
-215
lines changed

37 files changed

+472
-215
lines changed
 

‎compiler/rustc_middle/src/ty/subst.rs

Lines changed: 10 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_data_structures::intern::{Interned, WithStableHash};
1010
use rustc_hir::def_id::DefId;
1111
use rustc_macros::HashStable;
1212
use rustc_serialize::{self, Decodable, Encodable};
13-
use rustc_span::{Span, DUMMY_SP};
13+
use rustc_span::DUMMY_SP;
1414
use smallvec::SmallVec;
1515

1616
use core::intrinsics;
@@ -498,34 +498,14 @@ impl<'tcx> TypeFoldable<'tcx> for &'tcx ty::List<Ty<'tcx>> {
498498
}
499499
}
500500

501-
///////////////////////////////////////////////////////////////////////////
502-
// Public trait `Subst`
503-
//
504-
// Just call `foo.subst(tcx, substs)` to perform a substitution across
505-
// `foo`. Or use `foo.subst_spanned(tcx, substs, Some(span))` when
506-
// there is more information available (for better errors).
507-
501+
// Just call `foo.subst(tcx, substs)` to perform a substitution across `foo`.
508502
pub trait Subst<'tcx>: Sized {
509-
fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self {
510-
self.subst_spanned(tcx, substs, None)
511-
}
512-
513-
fn subst_spanned(
514-
self,
515-
tcx: TyCtxt<'tcx>,
516-
substs: &[GenericArg<'tcx>],
517-
span: Option<Span>,
518-
) -> Self;
503+
fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> Self;
519504
}
520505

521506
impl<'tcx, T: TypeFoldable<'tcx>> Subst<'tcx> for T {
522-
fn subst_spanned(
523-
self,
524-
tcx: TyCtxt<'tcx>,
525-
substs: &[GenericArg<'tcx>],
526-
span: Option<Span>,
527-
) -> T {
528-
let mut folder = SubstFolder { tcx, substs, span, binders_passed: 0 };
507+
fn subst(self, tcx: TyCtxt<'tcx>, substs: &[GenericArg<'tcx>]) -> T {
508+
let mut folder = SubstFolder { tcx, substs, binders_passed: 0 };
529509
self.fold_with(&mut folder)
530510
}
531511
}
@@ -537,9 +517,6 @@ struct SubstFolder<'a, 'tcx> {
537517
tcx: TyCtxt<'tcx>,
538518
substs: &'a [GenericArg<'tcx>],
539519

540-
/// The location for which the substitution is performed, if available.
541-
span: Option<Span>,
542-
543520
/// Number of region binders we have passed through while doing the substitution
544521
binders_passed: u32,
545522
}
@@ -571,13 +548,12 @@ impl<'a, 'tcx> TypeFolder<'tcx> for SubstFolder<'a, 'tcx> {
571548
match rk {
572549
Some(GenericArgKind::Lifetime(lt)) => self.shift_region_through_binders(lt),
573550
_ => {
574-
let span = self.span.unwrap_or(DUMMY_SP);
575551
let msg = format!(
576552
"Region parameter out of range \
577553
when substituting in region {} (index={})",
578554
data.name, data.index
579555
);
580-
span_bug!(span, "{}", msg);
556+
span_bug!(DUMMY_SP, "{}", msg);
581557
}
582558
}
583559
}
@@ -617,9 +593,8 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
617593
let ty = match opt_ty {
618594
Some(GenericArgKind::Type(ty)) => ty,
619595
Some(kind) => {
620-
let span = self.span.unwrap_or(DUMMY_SP);
621596
span_bug!(
622-
span,
597+
DUMMY_SP,
623598
"expected type for `{:?}` ({:?}/{}) but found {:?} \
624599
when substituting, substs={:?}",
625600
p,
@@ -630,9 +605,8 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
630605
);
631606
}
632607
None => {
633-
let span = self.span.unwrap_or(DUMMY_SP);
634608
span_bug!(
635-
span,
609+
DUMMY_SP,
636610
"type parameter `{:?}` ({:?}/{}) out of range \
637611
when substituting, substs={:?}",
638612
p,
@@ -652,9 +626,8 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
652626
let ct = match opt_ct {
653627
Some(GenericArgKind::Const(ct)) => ct,
654628
Some(kind) => {
655-
let span = self.span.unwrap_or(DUMMY_SP);
656629
span_bug!(
657-
span,
630+
DUMMY_SP,
658631
"expected const for `{:?}` ({:?}/{}) but found {:?} \
659632
when substituting substs={:?}",
660633
p,
@@ -665,9 +638,8 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
665638
);
666639
}
667640
None => {
668-
let span = self.span.unwrap_or(DUMMY_SP);
669641
span_bug!(
670-
span,
642+
DUMMY_SP,
671643
"const parameter `{:?}` ({:?}/{}) out of range \
672644
when substituting substs={:?}",
673645
p,

‎compiler/rustc_passes/src/check_attr.rs

Lines changed: 74 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
//! conflicts between multiple such attributes attached to the same
55
//! item.
66
7-
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MetaItemKind, NestedMetaItem};
7+
use rustc_ast::tokenstream::DelimSpan;
8+
use rustc_ast::{ast, AttrStyle, Attribute, Lit, LitKind, MacArgs, MetaItemKind, NestedMetaItem};
89
use rustc_data_structures::fx::FxHashMap;
910
use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan};
1011
use rustc_feature::{AttributeDuplicates, AttributeType, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP};
@@ -810,6 +811,68 @@ impl CheckAttrVisitor<'_> {
810811
}
811812
}
812813

814+
/// Checks `#[doc(hidden)]` attributes. Returns `true` if valid.
815+
fn check_doc_hidden(
816+
&self,
817+
attr: &Attribute,
818+
meta_index: usize,
819+
meta: &NestedMetaItem,
820+
hir_id: HirId,
821+
target: Target,
822+
) -> bool {
823+
if let Target::AssocConst
824+
| Target::AssocTy
825+
| Target::Method(MethodKind::Trait { body: true }) = target
826+
{
827+
let parent_hir_id = self.tcx.hir().get_parent_item(hir_id);
828+
let containing_item = self.tcx.hir().expect_item(parent_hir_id);
829+
830+
if Target::from_item(containing_item) == Target::Impl {
831+
let meta_items = attr.meta_item_list().unwrap();
832+
833+
let (span, replacement_span) = if meta_items.len() == 1 {
834+
(attr.span, attr.span)
835+
} else {
836+
let meta_span = meta.span();
837+
(
838+
meta_span,
839+
meta_span.until(match meta_items.get(meta_index + 1) {
840+
Some(next_item) => next_item.span(),
841+
None => match attr.get_normal_item().args {
842+
MacArgs::Delimited(DelimSpan { close, .. }, ..) => close,
843+
_ => unreachable!(),
844+
},
845+
}),
846+
)
847+
};
848+
849+
// FIXME: #[doc(hidden)] was previously erroneously allowed on trait impl items,
850+
// so for backward compatibility only emit a warning and do not mark it as invalid.
851+
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, span, |lint| {
852+
lint.build("`#[doc(hidden)]` is ignored on trait impl items")
853+
.warn(
854+
"this was previously accepted by the compiler but is \
855+
being phased out; it will become a hard error in \
856+
a future release!",
857+
)
858+
.note(
859+
"whether the impl item is `doc(hidden)` or not \
860+
entirely depends on the corresponding trait item",
861+
)
862+
.span_suggestion(
863+
replacement_span,
864+
"remove this attribute",
865+
String::new(),
866+
Applicability::MachineApplicable,
867+
)
868+
.emit();
869+
});
870+
}
871+
}
872+
873+
true
874+
}
875+
813876
/// Checks that an attribute is *not* used at the crate level. Returns `true` if valid.
814877
fn check_attr_not_crate_level(
815878
&self,
@@ -928,7 +991,7 @@ impl CheckAttrVisitor<'_> {
928991
let mut is_valid = true;
929992

930993
if let Some(mi) = attr.meta() && let Some(list) = mi.meta_item_list() {
931-
for meta in list {
994+
for (meta_index, meta) in list.into_iter().enumerate() {
932995
if let Some(i_meta) = meta.meta_item() {
933996
match i_meta.name_or_empty() {
934997
sym::alias
@@ -969,6 +1032,15 @@ impl CheckAttrVisitor<'_> {
9691032
is_valid = false;
9701033
}
9711034

1035+
sym::hidden if !self.check_doc_hidden(attr,
1036+
meta_index,
1037+
meta,
1038+
hir_id,
1039+
target,
1040+
) => {
1041+
is_valid = false;
1042+
}
1043+
9721044
// no_default_passes: deprecated
9731045
// passes: deprecated
9741046
// plugins: removed, but rustdoc warns about it itself

‎compiler/rustc_typeck/src/astconv/mod.rs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -523,11 +523,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
523523
self.astconv
524524
.normalize_ty(
525525
self.span,
526-
tcx.at(self.span).type_of(param.def_id).subst_spanned(
527-
tcx,
528-
substs,
529-
Some(self.span),
530-
),
526+
tcx.at(self.span).type_of(param.def_id).subst(tcx, substs),
531527
)
532528
.into()
533529
}
@@ -547,9 +543,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
547543
GenericParamDefKind::Const { has_default } => {
548544
let ty = tcx.at(self.span).type_of(param.def_id);
549545
if !infer_args && has_default {
550-
tcx.const_param_default(param.def_id)
551-
.subst_spanned(tcx, substs.unwrap(), Some(self.span))
552-
.into()
546+
tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into()
553547
} else {
554548
if infer_args {
555549
self.astconv.ct_infer(ty, Some(param), self.span).into()

‎compiler/rustc_typeck/src/check/expr.rs

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
4444
use rustc_middle::ty::error::ExpectedFound;
4545
use rustc_middle::ty::error::TypeError::{FieldMisMatch, Sorts};
4646
use rustc_middle::ty::subst::SubstsRef;
47-
use rustc_middle::ty::{self, AdtKind, Ty, TypeFoldable};
47+
use rustc_middle::ty::{self, AdtKind, DefIdTree, Ty, TypeFoldable};
4848
use rustc_session::parse::feature_err;
4949
use rustc_span::hygiene::DesugaringKind;
5050
use rustc_span::lev_distance::find_best_match_for_name;
@@ -2034,17 +2034,26 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20342034
base: &'tcx hir::Expr<'tcx>,
20352035
def_id: DefId,
20362036
) {
2037-
let local_id = def_id.expect_local();
2038-
let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_id);
2039-
let node = self.tcx.hir().get(hir_id);
2040-
2041-
if let Some(fields) = node.tuple_fields() {
2042-
let kind = match self.tcx.opt_def_kind(local_id) {
2043-
Some(DefKind::Ctor(of, _)) => of,
2044-
_ => return,
2045-
};
2037+
if let Some(local_id) = def_id.as_local() {
2038+
let hir_id = self.tcx.hir().local_def_id_to_hir_id(local_id);
2039+
let node = self.tcx.hir().get(hir_id);
2040+
2041+
if let Some(fields) = node.tuple_fields() {
2042+
let kind = match self.tcx.opt_def_kind(local_id) {
2043+
Some(DefKind::Ctor(of, _)) => of,
2044+
_ => return,
2045+
};
20462046

2047-
suggest_call_constructor(base.span, kind, fields.len(), err);
2047+
suggest_call_constructor(base.span, kind, fields.len(), err);
2048+
}
2049+
} else {
2050+
// The logic here isn't smart but `associated_item_def_ids`
2051+
// doesn't work nicely on local.
2052+
if let DefKind::Ctor(of, _) = self.tcx.def_kind(def_id) {
2053+
let parent_def_id = self.tcx.parent(def_id);
2054+
let fields = self.tcx.associated_item_def_ids(parent_def_id);
2055+
suggest_call_constructor(base.span, of, fields.len(), err);
2056+
}
20482057
}
20492058
}
20502059

‎compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1403,10 +1403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14031403
// is missing.
14041404
let default = tcx.type_of(param.def_id);
14051405
self.fcx
1406-
.normalize_ty(
1407-
self.span,
1408-
default.subst_spanned(tcx, substs.unwrap(), Some(self.span)),
1409-
)
1406+
.normalize_ty(self.span, default.subst(tcx, substs.unwrap()))
14101407
.into()
14111408
} else {
14121409
// If no type arguments were provided, we have to infer them.
@@ -1418,9 +1415,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
14181415
}
14191416
GenericParamDefKind::Const { has_default } => {
14201417
if !infer_args && has_default {
1421-
tcx.const_param_default(param.def_id)
1422-
.subst_spanned(tcx, substs.unwrap(), Some(self.span))
1423-
.into()
1418+
tcx.const_param_default(param.def_id).subst(tcx, substs.unwrap()).into()
14241419
} else {
14251420
self.fcx.var_for_def(self.span, param)
14261421
}

‎compiler/rustc_typeck/src/check/method/confirm.rs

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -462,19 +462,13 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
462462

463463
let sig = self.tcx.fn_sig(def_id);
464464

465-
// Instantiate late-bound regions and substitute the trait
466-
// parameters into the method type to get the actual method type.
467-
//
468-
// N.B., instantiate late-bound regions first so that
469-
// `instantiate_type_scheme` can normalize associated types that
470-
// may reference those regions.
471-
let method_sig = self.replace_bound_vars_with_fresh_vars(sig);
472-
debug!("late-bound lifetimes from method instantiated, method_sig={:?}", method_sig);
465+
let sig = sig.subst(self.tcx, all_substs);
466+
debug!("type scheme substituted, sig={:?}", sig);
473467

474-
let method_sig = method_sig.subst(self.tcx, all_substs);
475-
debug!("type scheme substituted, method_sig={:?}", method_sig);
468+
let sig = self.replace_bound_vars_with_fresh_vars(sig);
469+
debug!("late-bound lifetimes from method instantiated, sig={:?}", sig);
476470

477-
(method_sig, method_predicates)
471+
(sig, method_predicates)
478472
}
479473

480474
fn add_obligations(

‎compiler/rustc_typeck/src/check/method/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,8 +461,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
461461
// `instantiate_type_scheme` can normalize associated types that
462462
// may reference those regions.
463463
let fn_sig = tcx.fn_sig(def_id);
464-
let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig).0;
465464
let fn_sig = fn_sig.subst(self.tcx, substs);
465+
let fn_sig = self.replace_bound_vars_with_fresh_vars(span, infer::FnCall, fn_sig).0;
466466

467467
let InferOk { value, obligations: o } = if is_op {
468468
self.normalize_op_associated_types_in_as_infer_ok(span, fn_sig, opt_input_expr)

‎compiler/rustc_typeck/src/check/method/probe.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1784,12 +1784,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
17841784
let generics = self.tcx.generics_of(method);
17851785
assert_eq!(substs.len(), generics.parent_count as usize);
17861786

1787-
// Erase any late-bound regions from the method and substitute
1788-
// in the values from the substitution.
1789-
let xform_fn_sig = self.erase_late_bound_regions(fn_sig);
1790-
1791-
if generics.params.is_empty() {
1792-
xform_fn_sig.subst(self.tcx, substs)
1787+
let xform_fn_sig = if generics.params.is_empty() {
1788+
fn_sig.subst(self.tcx, substs)
17931789
} else {
17941790
let substs = InternalSubsts::for_item(self.tcx, method, |param, _| {
17951791
let i = param.index as usize;
@@ -1807,8 +1803,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
18071803
}
18081804
}
18091805
});
1810-
xform_fn_sig.subst(self.tcx, substs)
1811-
}
1806+
fn_sig.subst(self.tcx, substs)
1807+
};
1808+
1809+
self.erase_late_bound_regions(xform_fn_sig)
18121810
}
18131811

18141812
/// Gets the type of an impl and generate substitutions with placeholders.

‎library/alloc/src/collections/vec_deque/iter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ impl<'a, T> Iterator for Iter<'a, T> {
122122
}
123123

124124
#[inline]
125-
#[doc(hidden)]
126125
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
127126
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
128127
// that is in bounds.

‎library/alloc/src/collections/vec_deque/iter_mut.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ impl<'a, T> Iterator for IterMut<'a, T> {
100100
}
101101

102102
#[inline]
103-
#[doc(hidden)]
104103
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
105104
// Safety: The TrustedRandomAccess contract requires that callers only pass an index
106105
// that is in bounds.

‎library/alloc/src/vec/into_iter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,6 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
202202
self.len()
203203
}
204204

205-
#[doc(hidden)]
206205
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> Self::Item
207206
where
208207
Self: TrustedRandomAccessNoCoerce,

‎library/core/src/convert/num.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ macro_rules! impl_float_to_int {
2525
$(
2626
#[unstable(feature = "convert_float_to_int", issue = "67057")]
2727
impl FloatToInt<$Int> for $Float {
28-
#[doc(hidden)]
2928
#[inline]
3029
unsafe fn to_int_unchecked(self) -> $Int {
3130
// SAFETY: the safety contract must be upheld by the caller.

‎library/core/src/iter/adapters/cloned.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ where
6060
self.it.map(T::clone).fold(init, f)
6161
}
6262

63-
#[doc(hidden)]
6463
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
6564
where
6665
Self: TrustedRandomAccessNoCoerce,

‎library/core/src/iter/adapters/copied.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@ where
8181
self.it.advance_by(n)
8282
}
8383

84-
#[doc(hidden)]
8584
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> T
8685
where
8786
Self: TrustedRandomAccessNoCoerce,

‎library/core/src/iter/adapters/enumerate.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ where
128128
}
129129

130130
#[rustc_inherit_overflow_checks]
131-
#[doc(hidden)]
132131
#[inline]
133132
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> <Self as Iterator>::Item
134133
where

‎library/core/src/iter/adapters/fuse.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ where
129129
}
130130

131131
#[inline]
132-
#[doc(hidden)]
133132
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
134133
where
135134
Self: TrustedRandomAccessNoCoerce,

‎library/core/src/iter/adapters/map.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ where
124124
self.iter.fold(init, map_fold(self.f, g))
125125
}
126126

127-
#[doc(hidden)]
128127
#[inline]
129128
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> B
130129
where

‎library/core/src/iter/adapters/zip.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ where
9595
}
9696

9797
#[inline]
98-
#[doc(hidden)]
9998
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
10099
where
101100
Self: TrustedRandomAccessNoCoerce,

‎library/core/src/iter/range.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,6 @@ impl<A: Step> Iterator for ops::Range<A> {
752752
}
753753

754754
#[inline]
755-
#[doc(hidden)]
756755
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item
757756
where
758757
Self: TrustedRandomAccessNoCoerce,

‎library/core/src/num/f32.rs

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,15 @@ impl f32 {
393393
pub const MAX_10_EXP: i32 = 38;
394394

395395
/// Not a Number (NaN).
396+
///
397+
/// Note that IEEE-745 doesn't define just a single NaN value;
398+
/// a plethora of bit patterns are considered to be NaN.
399+
/// Furthermore, the standard makes a difference
400+
/// between a "signaling" and a "quiet" NaN,
401+
/// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
402+
/// This constant isn't guaranteed to equal to any specific NaN bitpattern,
403+
/// and the stability of its representation over Rust versions
404+
/// and target platforms isn't guaranteed.
396405
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
397406
pub const NAN: f32 = 0.0_f32 / 0.0_f32;
398407
/// Infinity (∞).
@@ -402,7 +411,7 @@ impl f32 {
402411
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
403412
pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32;
404413

405-
/// Returns `true` if this value is `NaN`.
414+
/// Returns `true` if this value is NaN.
406415
///
407416
/// ```
408417
/// let nan = f32::NAN;
@@ -455,7 +464,7 @@ impl f32 {
455464
(self == f32::INFINITY) | (self == f32::NEG_INFINITY)
456465
}
457466

458-
/// Returns `true` if this number is neither infinite nor `NaN`.
467+
/// Returns `true` if this number is neither infinite nor NaN.
459468
///
460469
/// ```
461470
/// let f = 7.0f32;
@@ -506,7 +515,7 @@ impl f32 {
506515
}
507516

508517
/// Returns `true` if the number is neither zero, infinite,
509-
/// [subnormal], or `NaN`.
518+
/// [subnormal], or NaN.
510519
///
511520
/// ```
512521
/// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32
@@ -622,8 +631,12 @@ impl f32 {
622631
}
623632
}
624633

625-
/// Returns `true` if `self` has a positive sign, including `+0.0`, `NaN`s with
626-
/// positive sign bit and positive infinity.
634+
/// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
635+
/// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any
636+
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
637+
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
638+
/// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
639+
/// See [explanation of NaN as a special value](f32) for more info.
627640
///
628641
/// ```
629642
/// let f = 7.0_f32;
@@ -640,8 +653,12 @@ impl f32 {
640653
!self.is_sign_negative()
641654
}
642655

643-
/// Returns `true` if `self` has a negative sign, including `-0.0`, `NaN`s with
644-
/// negative sign bit and negative infinity.
656+
/// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
657+
/// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any
658+
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
659+
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
660+
/// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
661+
/// See [explanation of NaN as a special value](f32) for more info.
645662
///
646663
/// ```
647664
/// let f = 7.0f32;
@@ -713,47 +730,47 @@ impl f32 {
713730
self * (value / 180.0f32)
714731
}
715732

716-
/// Returns the maximum of the two numbers.
733+
/// Returns the maximum of the two numbers, ignoring NaN.
717734
///
718-
/// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs.
719-
/// This matches the behavior of libm’s fmax.
735+
/// If one of the arguments is NaN, then the other argument is returned.
736+
/// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs;
737+
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
738+
/// This also matches the behavior of libm’s fmax.
720739
///
721740
/// ```
722741
/// let x = 1.0f32;
723742
/// let y = 2.0f32;
724743
///
725744
/// assert_eq!(x.max(y), y);
726745
/// ```
727-
///
728-
/// If one of the arguments is NaN, then the other argument is returned.
729746
#[must_use = "this returns the result of the comparison, without modifying either input"]
730747
#[stable(feature = "rust1", since = "1.0.0")]
731748
#[inline]
732749
pub fn max(self, other: f32) -> f32 {
733750
intrinsics::maxnumf32(self, other)
734751
}
735752

736-
/// Returns the minimum of the two numbers.
753+
/// Returns the minimum of the two numbers, ignoring NaN.
737754
///
738-
/// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs.
739-
/// This matches the behavior of libm’s fmin.
755+
/// If one of the arguments is NaN, then the other argument is returned.
756+
/// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs;
757+
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
758+
/// This also matches the behavior of libm’s fmin.
740759
///
741760
/// ```
742761
/// let x = 1.0f32;
743762
/// let y = 2.0f32;
744763
///
745764
/// assert_eq!(x.min(y), x);
746765
/// ```
747-
///
748-
/// If one of the arguments is NaN, then the other argument is returned.
749766
#[must_use = "this returns the result of the comparison, without modifying either input"]
750767
#[stable(feature = "rust1", since = "1.0.0")]
751768
#[inline]
752769
pub fn min(self, other: f32) -> f32 {
753770
intrinsics::minnumf32(self, other)
754771
}
755772

756-
/// Returns the maximum of the two numbers, propagating NaNs.
773+
/// Returns the maximum of the two numbers, propagating NaN.
757774
///
758775
/// This returns NaN when *either* argument is NaN, as opposed to
759776
/// [`f32::max`] which only returns NaN when *both* arguments are NaN.
@@ -770,6 +787,9 @@ impl f32 {
770787
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
771788
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
772789
/// Note that this follows the semantics specified in IEEE 754-2019.
790+
///
791+
/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
792+
/// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
773793
#[must_use = "this returns the result of the comparison, without modifying either input"]
774794
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
775795
#[inline]
@@ -785,7 +805,7 @@ impl f32 {
785805
}
786806
}
787807

788-
/// Returns the minimum of the two numbers, propagating NaNs.
808+
/// Returns the minimum of the two numbers, propagating NaN.
789809
///
790810
/// This returns NaN when *either* argument is NaN, as opposed to
791811
/// [`f32::min`] which only returns NaN when *both* arguments are NaN.
@@ -802,6 +822,9 @@ impl f32 {
802822
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
803823
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
804824
/// Note that this follows the semantics specified in IEEE 754-2019.
825+
///
826+
/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
827+
/// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
805828
#[must_use = "this returns the result of the comparison, without modifying either input"]
806829
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
807830
#[inline]
@@ -1009,6 +1032,9 @@ impl f32 {
10091032
/// Return the memory representation of this floating point number as a byte array in
10101033
/// big-endian (network) byte order.
10111034
///
1035+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1036+
/// portability of this operation (there are almost no issues).
1037+
///
10121038
/// # Examples
10131039
///
10141040
/// ```
@@ -1027,6 +1053,9 @@ impl f32 {
10271053
/// Return the memory representation of this floating point number as a byte array in
10281054
/// little-endian byte order.
10291055
///
1056+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1057+
/// portability of this operation (there are almost no issues).
1058+
///
10301059
/// # Examples
10311060
///
10321061
/// ```
@@ -1051,6 +1080,9 @@ impl f32 {
10511080
/// [`to_be_bytes`]: f32::to_be_bytes
10521081
/// [`to_le_bytes`]: f32::to_le_bytes
10531082
///
1083+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1084+
/// portability of this operation (there are almost no issues).
1085+
///
10541086
/// # Examples
10551087
///
10561088
/// ```
@@ -1075,6 +1107,9 @@ impl f32 {
10751107

10761108
/// Create a floating point value from its representation as a byte array in big endian.
10771109
///
1110+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1111+
/// portability of this operation (there are almost no issues).
1112+
///
10781113
/// # Examples
10791114
///
10801115
/// ```
@@ -1091,6 +1126,9 @@ impl f32 {
10911126

10921127
/// Create a floating point value from its representation as a byte array in little endian.
10931128
///
1129+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1130+
/// portability of this operation (there are almost no issues).
1131+
///
10941132
/// # Examples
10951133
///
10961134
/// ```
@@ -1114,6 +1152,9 @@ impl f32 {
11141152
/// [`from_be_bytes`]: f32::from_be_bytes
11151153
/// [`from_le_bytes`]: f32::from_le_bytes
11161154
///
1155+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1156+
/// portability of this operation (there are almost no issues).
1157+
///
11171158
/// # Examples
11181159
///
11191160
/// ```

‎library/core/src/num/f64.rs

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,15 @@ impl f64 {
392392
pub const MAX_10_EXP: i32 = 308;
393393

394394
/// Not a Number (NaN).
395+
///
396+
/// Note that IEEE-745 doesn't define just a single NaN value;
397+
/// a plethora of bit patterns are considered to be NaN.
398+
/// Furthermore, the standard makes a difference
399+
/// between a "signaling" and a "quiet" NaN,
400+
/// and allows inspecting its "payload" (the unspecified bits in the bit pattern).
401+
/// This constant isn't guaranteed to equal to any specific NaN bitpattern,
402+
/// and the stability of its representation over Rust versions
403+
/// and target platforms isn't guaranteed.
395404
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
396405
pub const NAN: f64 = 0.0_f64 / 0.0_f64;
397406
/// Infinity (∞).
@@ -401,7 +410,7 @@ impl f64 {
401410
#[stable(feature = "assoc_int_consts", since = "1.43.0")]
402411
pub const NEG_INFINITY: f64 = -1.0_f64 / 0.0_f64;
403412

404-
/// Returns `true` if this value is `NaN`.
413+
/// Returns `true` if this value is NaN.
405414
///
406415
/// ```
407416
/// let nan = f64::NAN;
@@ -456,7 +465,7 @@ impl f64 {
456465
(self == f64::INFINITY) | (self == f64::NEG_INFINITY)
457466
}
458467

459-
/// Returns `true` if this number is neither infinite nor `NaN`.
468+
/// Returns `true` if this number is neither infinite nor NaN.
460469
///
461470
/// ```
462471
/// let f = 7.0f64;
@@ -507,7 +516,7 @@ impl f64 {
507516
}
508517

509518
/// Returns `true` if the number is neither zero, infinite,
510-
/// [subnormal], or `NaN`.
519+
/// [subnormal], or NaN.
511520
///
512521
/// ```
513522
/// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308f64
@@ -614,8 +623,12 @@ impl f64 {
614623
}
615624
}
616625

617-
/// Returns `true` if `self` has a positive sign, including `+0.0`, `NaN`s with
618-
/// positive sign bit and positive infinity.
626+
/// Returns `true` if `self` has a positive sign, including `+0.0`, NaNs with
627+
/// positive sign bit and positive infinity. Note that IEEE-745 doesn't assign any
628+
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
629+
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
630+
/// `is_sign_positive` on a NaN might produce an unexpected result in some cases.
631+
/// See [explanation of NaN as a special value](f32) for more info.
619632
///
620633
/// ```
621634
/// let f = 7.0_f64;
@@ -641,8 +654,12 @@ impl f64 {
641654
self.is_sign_positive()
642655
}
643656

644-
/// Returns `true` if `self` has a negative sign, including `-0.0`, `NaN`s with
645-
/// negative sign bit and negative infinity.
657+
/// Returns `true` if `self` has a negative sign, including `-0.0`, NaNs with
658+
/// negative sign bit and negative infinity. Note that IEEE-745 doesn't assign any
659+
/// meaning to the sign bit in case of a NaN, and as Rust doesn't guarantee that
660+
/// the bit pattern of NaNs are conserved over arithmetic operations, the result of
661+
/// `is_sign_negative` on a NaN might produce an unexpected result in some cases.
662+
/// See [explanation of NaN as a special value](f32) for more info.
646663
///
647664
/// ```
648665
/// let f = 7.0_f64;
@@ -724,47 +741,47 @@ impl f64 {
724741
self * (value / 180.0)
725742
}
726743

727-
/// Returns the maximum of the two numbers.
744+
/// Returns the maximum of the two numbers, ignoring NaN.
728745
///
729-
/// Follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs.
730-
/// This matches the behavior of libm’s fmax.
746+
/// If one of the arguments is NaN, then the other argument is returned.
747+
/// This follows the IEEE-754 2008 semantics for maxNum, except for handling of signaling NaNs;
748+
/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.
749+
/// This also matches the behavior of libm’s fmax.
731750
///
732751
/// ```
733752
/// let x = 1.0_f64;
734753
/// let y = 2.0_f64;
735754
///
736755
/// assert_eq!(x.max(y), y);
737756
/// ```
738-
///
739-
/// If one of the arguments is NaN, then the other argument is returned.
740757
#[must_use = "this returns the result of the comparison, without modifying either input"]
741758
#[stable(feature = "rust1", since = "1.0.0")]
742759
#[inline]
743760
pub fn max(self, other: f64) -> f64 {
744761
intrinsics::maxnumf64(self, other)
745762
}
746763

747-
/// Returns the minimum of the two numbers.
764+
/// Returns the minimum of the two numbers, ignoring NaN.
748765
///
749-
/// Follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs.
750-
/// This matches the behavior of libm’s fmin.
766+
/// If one of the arguments is NaN, then the other argument is returned.
767+
/// This follows the IEEE-754 2008 semantics for minNum, except for handling of signaling NaNs;
768+
/// this function handles all NaNs the same way and avoids minNum's problems with associativity.
769+
/// This also matches the behavior of libm’s fmin.
751770
///
752771
/// ```
753772
/// let x = 1.0_f64;
754773
/// let y = 2.0_f64;
755774
///
756775
/// assert_eq!(x.min(y), x);
757776
/// ```
758-
///
759-
/// If one of the arguments is NaN, then the other argument is returned.
760777
#[must_use = "this returns the result of the comparison, without modifying either input"]
761778
#[stable(feature = "rust1", since = "1.0.0")]
762779
#[inline]
763780
pub fn min(self, other: f64) -> f64 {
764781
intrinsics::minnumf64(self, other)
765782
}
766783

767-
/// Returns the maximum of the two numbers, propagating NaNs.
784+
/// Returns the maximum of the two numbers, propagating NaN.
768785
///
769786
/// This returns NaN when *either* argument is NaN, as opposed to
770787
/// [`f64::max`] which only returns NaN when *both* arguments are NaN.
@@ -781,6 +798,9 @@ impl f64 {
781798
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater
782799
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
783800
/// Note that this follows the semantics specified in IEEE 754-2019.
801+
///
802+
/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
803+
/// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
784804
#[must_use = "this returns the result of the comparison, without modifying either input"]
785805
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
786806
#[inline]
@@ -796,7 +816,7 @@ impl f64 {
796816
}
797817
}
798818

799-
/// Returns the minimum of the two numbers, propagating NaNs.
819+
/// Returns the minimum of the two numbers, propagating NaN.
800820
///
801821
/// This returns NaN when *either* argument is NaN, as opposed to
802822
/// [`f64::min`] which only returns NaN when *both* arguments are NaN.
@@ -813,6 +833,9 @@ impl f64 {
813833
/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser
814834
/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.
815835
/// Note that this follows the semantics specified in IEEE 754-2019.
836+
///
837+
/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN
838+
/// operand is conserved; see [explanation of NaN as a special value](f32) for more info.
816839
#[must_use = "this returns the result of the comparison, without modifying either input"]
817840
#[unstable(feature = "float_minimum_maximum", issue = "91079")]
818841
#[inline]
@@ -1007,6 +1030,9 @@ impl f64 {
10071030
/// Return the memory representation of this floating point number as a byte array in
10081031
/// big-endian (network) byte order.
10091032
///
1033+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1034+
/// portability of this operation (there are almost no issues).
1035+
///
10101036
/// # Examples
10111037
///
10121038
/// ```
@@ -1025,6 +1051,9 @@ impl f64 {
10251051
/// Return the memory representation of this floating point number as a byte array in
10261052
/// little-endian byte order.
10271053
///
1054+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1055+
/// portability of this operation (there are almost no issues).
1056+
///
10281057
/// # Examples
10291058
///
10301059
/// ```
@@ -1049,6 +1078,9 @@ impl f64 {
10491078
/// [`to_be_bytes`]: f64::to_be_bytes
10501079
/// [`to_le_bytes`]: f64::to_le_bytes
10511080
///
1081+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1082+
/// portability of this operation (there are almost no issues).
1083+
///
10521084
/// # Examples
10531085
///
10541086
/// ```
@@ -1073,6 +1105,9 @@ impl f64 {
10731105

10741106
/// Create a floating point value from its representation as a byte array in big endian.
10751107
///
1108+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1109+
/// portability of this operation (there are almost no issues).
1110+
///
10761111
/// # Examples
10771112
///
10781113
/// ```
@@ -1089,6 +1124,9 @@ impl f64 {
10891124

10901125
/// Create a floating point value from its representation as a byte array in little endian.
10911126
///
1127+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1128+
/// portability of this operation (there are almost no issues).
1129+
///
10921130
/// # Examples
10931131
///
10941132
/// ```
@@ -1112,6 +1150,9 @@ impl f64 {
11121150
/// [`from_be_bytes`]: f64::from_be_bytes
11131151
/// [`from_le_bytes`]: f64::from_le_bytes
11141152
///
1153+
/// See [`from_bits`](Self::from_bits) for some discussion of the
1154+
/// portability of this operation (there are almost no issues).
1155+
///
11151156
/// # Examples
11161157
///
11171158
/// ```

‎library/core/src/primitive_docs.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,10 +977,22 @@ mod prim_tuple {}
977977
/// like `1.0 / 0.0`.
978978
/// - [NaN (not a number)](#associatedconstant.NAN): this value results from
979979
/// calculations like `(-1.0).sqrt()`. NaN has some potentially unexpected
980-
/// behavior: it is unequal to any float, including itself! It is also neither
981-
/// smaller nor greater than any float, making it impossible to sort. Lastly,
982-
/// it is considered infectious as almost all calculations where one of the
983-
/// operands is NaN will also result in NaN.
980+
/// behavior:
981+
/// - It is unequal to any float, including itself! This is the reason `f32`
982+
/// doesn't implement the `Eq` trait.
983+
/// - It is also neither smaller nor greater than any float, making it
984+
/// impossible to sort by the default comparison operation, which is the
985+
/// reason `f32` doesn't implement the `Ord` trait.
986+
/// - It is also considered *infectious* as almost all calculations where one
987+
/// of the operands is NaN will also result in NaN. The explanations on this
988+
/// page only explicitly document behavior on NaN operands if this default
989+
/// is deviated from.
990+
/// - Lastly, there are multiple bit patterns that are considered NaN.
991+
/// Rust does not currently guarantee that the bit patterns of NaN are
992+
/// preserved over arithmetic operations, and they are not guaranteed to be
993+
/// portable or even fully deterministic! This means that there may be some
994+
/// surprising results upon inspecting the bit patterns,
995+
/// as the same calculations might produce NaNs with different bit patterns.
984996
///
985997
/// For more information on floating point numbers, see [Wikipedia][wikipedia].
986998
///

‎library/core/src/slice/iter.rs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1322,7 +1322,6 @@ impl<'a, T> Iterator for Windows<'a, T> {
13221322
}
13231323
}
13241324

1325-
#[doc(hidden)]
13261325
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
13271326
// SAFETY: since the caller guarantees that `i` is in bounds,
13281327
// which means that `i` cannot overflow an `isize`, and the
@@ -1478,7 +1477,6 @@ impl<'a, T> Iterator for Chunks<'a, T> {
14781477
}
14791478
}
14801479

1481-
#[doc(hidden)]
14821480
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
14831481
let start = idx * self.chunk_size;
14841482
// SAFETY: the caller guarantees that `i` is in bounds,
@@ -1657,7 +1655,6 @@ impl<'a, T> Iterator for ChunksMut<'a, T> {
16571655
}
16581656
}
16591657

1660-
#[doc(hidden)]
16611658
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
16621659
let start = idx * self.chunk_size;
16631660
// SAFETY: see comments for `Chunks::__iterator_get_unchecked`.
@@ -1830,7 +1827,6 @@ impl<'a, T> Iterator for ChunksExact<'a, T> {
18301827
self.next_back()
18311828
}
18321829

1833-
#[doc(hidden)]
18341830
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
18351831
let start = idx * self.chunk_size;
18361832
// SAFETY: mostly identical to `Chunks::__iterator_get_unchecked`.
@@ -1984,7 +1980,6 @@ impl<'a, T> Iterator for ChunksExactMut<'a, T> {
19841980
self.next_back()
19851981
}
19861982

1987-
#[doc(hidden)]
19881983
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
19891984
let start = idx * self.chunk_size;
19901985
// SAFETY: see comments for `ChunksMut::__iterator_get_unchecked`.
@@ -2248,7 +2243,6 @@ impl<'a, T, const N: usize> Iterator for ArrayChunks<'a, T, N> {
22482243
self.iter.last()
22492244
}
22502245

2251-
#[doc(hidden)]
22522246
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a [T; N] {
22532247
// SAFETY: The safety guarantees of `__iterator_get_unchecked` are
22542248
// transferred to the caller.
@@ -2367,7 +2361,6 @@ impl<'a, T, const N: usize> Iterator for ArrayChunksMut<'a, T, N> {
23672361
self.iter.last()
23682362
}
23692363

2370-
#[doc(hidden)]
23712364
unsafe fn __iterator_get_unchecked(&mut self, i: usize) -> &'a mut [T; N] {
23722365
// SAFETY: The safety guarantees of `__iterator_get_unchecked` are transferred to
23732366
// the caller.
@@ -2520,7 +2513,6 @@ impl<'a, T> Iterator for RChunks<'a, T> {
25202513
}
25212514
}
25222515

2523-
#[doc(hidden)]
25242516
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
25252517
let end = self.v.len() - idx * self.chunk_size;
25262518
let start = match end.checked_sub(self.chunk_size) {
@@ -2689,7 +2681,6 @@ impl<'a, T> Iterator for RChunksMut<'a, T> {
26892681
}
26902682
}
26912683

2692-
#[doc(hidden)]
26932684
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
26942685
let end = self.v.len() - idx * self.chunk_size;
26952686
let start = match end.checked_sub(self.chunk_size) {
@@ -2856,7 +2847,6 @@ impl<'a, T> Iterator for RChunksExact<'a, T> {
28562847
self.next_back()
28572848
}
28582849

2859-
#[doc(hidden)]
28602850
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
28612851
let end = self.v.len() - idx * self.chunk_size;
28622852
let start = end - self.chunk_size;
@@ -3016,7 +3006,6 @@ impl<'a, T> Iterator for RChunksExactMut<'a, T> {
30163006
self.next_back()
30173007
}
30183008

3019-
#[doc(hidden)]
30203009
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
30213010
let end = self.v.len() - idx * self.chunk_size;
30223011
let start = end - self.chunk_size;

‎library/core/src/slice/iter/macros.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,6 @@ macro_rules! iterator {
325325
None
326326
}
327327

328-
#[doc(hidden)]
329328
#[inline]
330329
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> Self::Item {
331330
// SAFETY: the caller must guarantee that `i` is in bounds of

‎library/core/src/str/iter.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,6 @@ impl Iterator for Bytes<'_> {
298298
}
299299

300300
#[inline]
301-
#[doc(hidden)]
302301
unsafe fn __iterator_get_unchecked(&mut self, idx: usize) -> u8 {
303302
// SAFETY: the caller must uphold the safety contract
304303
// for `Iterator::__iterator_get_unchecked`.

‎library/std/src/f32.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub use core::f32::{
2929

3030
#[cfg(not(test))]
3131
impl f32 {
32-
/// Returns the largest integer less than or equal to a number.
32+
/// Returns the largest integer less than or equal to `self`.
3333
///
3434
/// # Examples
3535
///
@@ -50,7 +50,7 @@ impl f32 {
5050
unsafe { intrinsics::floorf32(self) }
5151
}
5252

53-
/// Returns the smallest integer greater than or equal to a number.
53+
/// Returns the smallest integer greater than or equal to `self`.
5454
///
5555
/// # Examples
5656
///
@@ -69,7 +69,7 @@ impl f32 {
6969
unsafe { intrinsics::ceilf32(self) }
7070
}
7171

72-
/// Returns the nearest integer to a number. Round half-way cases away from
72+
/// Returns the nearest integer to `self`. Round half-way cases away from
7373
/// `0.0`.
7474
///
7575
/// # Examples
@@ -89,7 +89,8 @@ impl f32 {
8989
unsafe { intrinsics::roundf32(self) }
9090
}
9191

92-
/// Returns the integer part of a number.
92+
/// Returns the integer part of `self`.
93+
/// This means that non-integer numbers are always truncated towards zero.
9394
///
9495
/// # Examples
9596
///
@@ -110,7 +111,7 @@ impl f32 {
110111
unsafe { intrinsics::truncf32(self) }
111112
}
112113

113-
/// Returns the fractional part of a number.
114+
/// Returns the fractional part of `self`.
114115
///
115116
/// # Examples
116117
///
@@ -131,8 +132,7 @@ impl f32 {
131132
self - self.trunc()
132133
}
133134

134-
/// Computes the absolute value of `self`. Returns `NAN` if the
135-
/// number is `NAN`.
135+
/// Computes the absolute value of `self`.
136136
///
137137
/// # Examples
138138
///
@@ -160,7 +160,7 @@ impl f32 {
160160
///
161161
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
162162
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
163-
/// - `NAN` if the number is `NAN`
163+
/// - NaN if the number is NaN
164164
///
165165
/// # Examples
166166
///
@@ -184,8 +184,10 @@ impl f32 {
184184
/// `sign`.
185185
///
186186
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
187-
/// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of
188-
/// `sign` is returned.
187+
/// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of
188+
/// `sign` is returned. Note, however, that conserving the sign bit on NaN
189+
/// across arithmetical operations is not generally guaranteed.
190+
/// See [explanation of NaN as a special value](primitive@f32) for more info.
189191
///
190192
/// # Examples
191193
///
@@ -298,7 +300,9 @@ impl f32 {
298300

299301
/// Raises a number to an integer power.
300302
///
301-
/// Using this function is generally faster than using `powf`
303+
/// Using this function is generally faster than using `powf`.
304+
/// It might have a different sequence of rounding operations than `powf`,
305+
/// so the results are not guaranteed to agree.
302306
///
303307
/// # Examples
304308
///

‎library/std/src/f64.rs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub use core::f64::{
2929

3030
#[cfg(not(test))]
3131
impl f64 {
32-
/// Returns the largest integer less than or equal to a number.
32+
/// Returns the largest integer less than or equal to `self`.
3333
///
3434
/// # Examples
3535
///
@@ -50,7 +50,7 @@ impl f64 {
5050
unsafe { intrinsics::floorf64(self) }
5151
}
5252

53-
/// Returns the smallest integer greater than or equal to a number.
53+
/// Returns the smallest integer greater than or equal to `self`.
5454
///
5555
/// # Examples
5656
///
@@ -69,7 +69,7 @@ impl f64 {
6969
unsafe { intrinsics::ceilf64(self) }
7070
}
7171

72-
/// Returns the nearest integer to a number. Round half-way cases away from
72+
/// Returns the nearest integer to `self`. Round half-way cases away from
7373
/// `0.0`.
7474
///
7575
/// # Examples
@@ -89,7 +89,8 @@ impl f64 {
8989
unsafe { intrinsics::roundf64(self) }
9090
}
9191

92-
/// Returns the integer part of a number.
92+
/// Returns the integer part of `self`.
93+
/// This means that non-integer numbers are always truncated towards zero.
9394
///
9495
/// # Examples
9596
///
@@ -110,7 +111,7 @@ impl f64 {
110111
unsafe { intrinsics::truncf64(self) }
111112
}
112113

113-
/// Returns the fractional part of a number.
114+
/// Returns the fractional part of `self`.
114115
///
115116
/// # Examples
116117
///
@@ -131,8 +132,7 @@ impl f64 {
131132
self - self.trunc()
132133
}
133134

134-
/// Computes the absolute value of `self`. Returns `NAN` if the
135-
/// number is `NAN`.
135+
/// Computes the absolute value of `self`.
136136
///
137137
/// # Examples
138138
///
@@ -160,7 +160,7 @@ impl f64 {
160160
///
161161
/// - `1.0` if the number is positive, `+0.0` or `INFINITY`
162162
/// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
163-
/// - `NAN` if the number is `NAN`
163+
/// - NaN if the number is NaN
164164
///
165165
/// # Examples
166166
///
@@ -184,8 +184,10 @@ impl f64 {
184184
/// `sign`.
185185
///
186186
/// Equal to `self` if the sign of `self` and `sign` are the same, otherwise
187-
/// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of
188-
/// `sign` is returned.
187+
/// equal to `-self`. If `self` is a NaN, then a NaN with the sign bit of
188+
/// `sign` is returned. Note, however, that conserving the sign bit on NaN
189+
/// across arithmetical operations is not generally guaranteed.
190+
/// See [explanation of NaN as a special value](primitive@f32) for more info.
189191
///
190192
/// # Examples
191193
///
@@ -298,7 +300,9 @@ impl f64 {
298300

299301
/// Raises a number to an integer power.
300302
///
301-
/// Using this function is generally faster than using `powf`
303+
/// Using this function is generally faster than using `powf`.
304+
/// It might have a different sequence of rounding operations than `powf`,
305+
/// so the results are not guaranteed to agree.
302306
///
303307
/// # Examples
304308
///

‎library/std/src/ffi/os_str.rs

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,23 +1222,6 @@ impl OsStr {
12221222
}
12231223
}
12241224

1225-
#[unstable(feature = "slice_concat_ext", issue = "27747")]
1226-
impl<S: Borrow<OsStr>> alloc::slice::Join<&OsStr> for [S] {
1227-
type Output = OsString;
1228-
1229-
fn join(slice: &Self, sep: &OsStr) -> OsString {
1230-
let Some(first) = slice.first() else {
1231-
return OsString::new();
1232-
};
1233-
let first = first.borrow().to_owned();
1234-
slice[1..].iter().fold(first, |mut a, b| {
1235-
a.push(sep);
1236-
a.push(b.borrow());
1237-
a
1238-
})
1239-
}
1240-
}
1241-
12421225
#[stable(feature = "rust1", since = "1.0.0")]
12431226
impl Borrow<OsStr> for OsString {
12441227
#[inline]

‎library/std/src/ffi/os_str/tests.rs

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,20 +84,6 @@ fn test_os_string_reserve_exact() {
8484
assert!(os_string.capacity() >= 33)
8585
}
8686

87-
#[test]
88-
fn test_os_string_join() {
89-
let strings = [OsStr::new("hello"), OsStr::new("dear"), OsStr::new("world")];
90-
assert_eq!("hello", strings[..1].join(OsStr::new(" ")));
91-
assert_eq!("hello dear world", strings.join(OsStr::new(" ")));
92-
assert_eq!("hellodearworld", strings.join(OsStr::new("")));
93-
assert_eq!("hello.\n dear.\n world", strings.join(OsStr::new(".\n ")));
94-
95-
assert_eq!("dear world", strings[1..].join(&OsString::from(" ")));
96-
97-
let strings_abc = [OsString::from("a"), OsString::from("b"), OsString::from("c")];
98-
assert_eq!("a b c", strings_abc.join(OsStr::new(" ")));
99-
}
100-
10187
#[test]
10288
fn test_os_string_default() {
10389
let os_string: OsString = Default::default();

‎library/std/src/lib.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,6 @@
241241
#![feature(intra_doc_pointers)]
242242
#![feature(lang_items)]
243243
#![feature(let_chains)]
244-
#![feature(let_else)]
245244
#![feature(linkage)]
246245
#![feature(min_specialization)]
247246
#![feature(must_not_suspend)]
@@ -302,7 +301,6 @@
302301
#![feature(toowned_clone_into)]
303302
#![feature(try_reserve_kind)]
304303
#![feature(vec_into_raw_parts)]
305-
#![feature(slice_concat_trait)]
306304
//
307305
// Library features (unwind):
308306
#![feature(panic_unwind)]

‎library/std/src/primitive_docs.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,10 +977,22 @@ mod prim_tuple {}
977977
/// like `1.0 / 0.0`.
978978
/// - [NaN (not a number)](#associatedconstant.NAN): this value results from
979979
/// calculations like `(-1.0).sqrt()`. NaN has some potentially unexpected
980-
/// behavior: it is unequal to any float, including itself! It is also neither
981-
/// smaller nor greater than any float, making it impossible to sort. Lastly,
982-
/// it is considered infectious as almost all calculations where one of the
983-
/// operands is NaN will also result in NaN.
980+
/// behavior:
981+
/// - It is unequal to any float, including itself! This is the reason `f32`
982+
/// doesn't implement the `Eq` trait.
983+
/// - It is also neither smaller nor greater than any float, making it
984+
/// impossible to sort by the default comparison operation, which is the
985+
/// reason `f32` doesn't implement the `Ord` trait.
986+
/// - It is also considered *infectious* as almost all calculations where one
987+
/// of the operands is NaN will also result in NaN. The explanations on this
988+
/// page only explicitly document behavior on NaN operands if this default
989+
/// is deviated from.
990+
/// - Lastly, there are multiple bit patterns that are considered NaN.
991+
/// Rust does not currently guarantee that the bit patterns of NaN are
992+
/// preserved over arithmetic operations, and they are not guaranteed to be
993+
/// portable or even fully deterministic! This means that there may be some
994+
/// surprising results upon inspecting the bit patterns,
995+
/// as the same calculations might produce NaNs with different bit patterns.
984996
///
985997
/// For more information on floating point numbers, see [Wikipedia][wikipedia].
986998
///

‎src/librustdoc/html/static/js/search.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ window.initSearch = rawSearchIndex => {
10891089
return parsedQuery.literalSearch ? MAX_LEV_DISTANCE + 1 : lev;
10901090
}
10911091

1092-
function checkPath(contains, lastElem, ty) {
1092+
function checkPath(contains, ty) {
10931093
if (contains.length === 0) {
10941094
return 0;
10951095
}
@@ -1306,7 +1306,7 @@ window.initSearch = rawSearchIndex => {
13061306
}
13071307

13081308
if (elem.fullPath.length > 1) {
1309-
lev = checkPath(elem.pathWithoutLast, elem.pathLast, row);
1309+
lev = checkPath(elem.pathWithoutLast, row);
13101310
if (lev > MAX_LEV_DISTANCE || (parsedQuery.literalSearch && lev !== 0)) {
13111311
return;
13121312
} else if (lev > 0) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#![deny(unused_attributes)]
2+
#![crate_type = "lib"]
3+
// run-rustfix
4+
5+
pub trait Trait {
6+
type It;
7+
const IT: ();
8+
fn it0();
9+
fn it1();
10+
fn it2();
11+
}
12+
13+
pub struct Implementor;
14+
15+
impl Trait for Implementor {
16+
17+
type It = ();
18+
//~^^ ERROR `#[doc(hidden)]` is ignored
19+
//~| WARNING this was previously accepted
20+
21+
22+
const IT: () = ();
23+
//~^^ ERROR `#[doc(hidden)]` is ignored
24+
//~| WARNING this was previously accepted
25+
26+
#[doc(alias = "aka")]
27+
fn it0() {}
28+
//~^^ ERROR `#[doc(hidden)]` is ignored
29+
//~| WARNING this was previously accepted
30+
31+
#[doc(alias = "this", )]
32+
fn it1() {}
33+
//~^^ ERROR `#[doc(hidden)]` is ignored
34+
//~| WARNING this was previously accepted
35+
36+
#[doc()]
37+
fn it2() {}
38+
//~^^ ERROR `#[doc(hidden)]` is ignored
39+
//~| WARNING this was previously accepted
40+
//~| ERROR `#[doc(hidden)]` is ignored
41+
//~| WARNING this was previously accepted
42+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#![deny(unused_attributes)]
2+
#![crate_type = "lib"]
3+
// run-rustfix
4+
5+
pub trait Trait {
6+
type It;
7+
const IT: ();
8+
fn it0();
9+
fn it1();
10+
fn it2();
11+
}
12+
13+
pub struct Implementor;
14+
15+
impl Trait for Implementor {
16+
#[doc(hidden)]
17+
type It = ();
18+
//~^^ ERROR `#[doc(hidden)]` is ignored
19+
//~| WARNING this was previously accepted
20+
21+
#[doc(hidden)]
22+
const IT: () = ();
23+
//~^^ ERROR `#[doc(hidden)]` is ignored
24+
//~| WARNING this was previously accepted
25+
26+
#[doc(hidden, alias = "aka")]
27+
fn it0() {}
28+
//~^^ ERROR `#[doc(hidden)]` is ignored
29+
//~| WARNING this was previously accepted
30+
31+
#[doc(alias = "this", hidden,)]
32+
fn it1() {}
33+
//~^^ ERROR `#[doc(hidden)]` is ignored
34+
//~| WARNING this was previously accepted
35+
36+
#[doc(hidden, hidden)]
37+
fn it2() {}
38+
//~^^ ERROR `#[doc(hidden)]` is ignored
39+
//~| WARNING this was previously accepted
40+
//~| ERROR `#[doc(hidden)]` is ignored
41+
//~| WARNING this was previously accepted
42+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
error: `#[doc(hidden)]` is ignored on trait impl items
2+
--> $DIR/unused-attr-doc-hidden.rs:16:5
3+
|
4+
LL | #[doc(hidden)]
5+
| ^^^^^^^^^^^^^^ help: remove this attribute
6+
|
7+
note: the lint level is defined here
8+
--> $DIR/unused-attr-doc-hidden.rs:1:9
9+
|
10+
LL | #![deny(unused_attributes)]
11+
| ^^^^^^^^^^^^^^^^^
12+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
13+
= note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
14+
15+
error: `#[doc(hidden)]` is ignored on trait impl items
16+
--> $DIR/unused-attr-doc-hidden.rs:21:5
17+
|
18+
LL | #[doc(hidden)]
19+
| ^^^^^^^^^^^^^^ help: remove this attribute
20+
|
21+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
22+
= note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
23+
24+
error: `#[doc(hidden)]` is ignored on trait impl items
25+
--> $DIR/unused-attr-doc-hidden.rs:26:11
26+
|
27+
LL | #[doc(hidden, alias = "aka")]
28+
| ^^^^^^--
29+
| |
30+
| help: remove this attribute
31+
|
32+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
33+
= note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
34+
35+
error: `#[doc(hidden)]` is ignored on trait impl items
36+
--> $DIR/unused-attr-doc-hidden.rs:31:27
37+
|
38+
LL | #[doc(alias = "this", hidden,)]
39+
| ^^^^^^-
40+
| |
41+
| help: remove this attribute
42+
|
43+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
44+
= note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
45+
46+
error: `#[doc(hidden)]` is ignored on trait impl items
47+
--> $DIR/unused-attr-doc-hidden.rs:36:11
48+
|
49+
LL | #[doc(hidden, hidden)]
50+
| ^^^^^^--
51+
| |
52+
| help: remove this attribute
53+
|
54+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
55+
= note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
56+
57+
error: `#[doc(hidden)]` is ignored on trait impl items
58+
--> $DIR/unused-attr-doc-hidden.rs:36:19
59+
|
60+
LL | #[doc(hidden, hidden)]
61+
| ^^^^^^ help: remove this attribute
62+
|
63+
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
64+
= note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
65+
66+
error: aborting due to 6 previous errors
67+

‎src/test/ui/typeck/issue-96738.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
fn main() {
22
Some.nonexistent_method(); //~ ERROR: no method named `nonexistent_method` found
3+
Some.nonexistent_field; //~ ERROR: no field `nonexistent_field`
34
}

‎src/test/ui/typeck/issue-96738.stderr

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,20 @@ help: call the constructor
1111
LL | (Some)(_).nonexistent_method();
1212
| + ++++
1313

14-
error: aborting due to previous error
14+
error[E0609]: no field `nonexistent_field` on type `fn(_) -> Option<_> {Option::<_>::Some}`
15+
--> $DIR/issue-96738.rs:3:10
16+
|
17+
LL | Some.nonexistent_field;
18+
| ---- ^^^^^^^^^^^^^^^^^
19+
| |
20+
| this is the constructor of an enum variant
21+
|
22+
help: call the constructor
23+
|
24+
LL | (Some)(_).nonexistent_field;
25+
| + ++++
26+
27+
error: aborting due to 2 previous errors
1528

16-
For more information about this error, try `rustc --explain E0599`.
29+
Some errors have detailed explanations: E0599, E0609.
30+
For more information about an error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)
This repository has been archived.