diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs index 0eafab017c7f3..aab005dacf3e2 100644 --- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs +++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs @@ -1576,17 +1576,10 @@ impl<'tcx> TypeVisitor> for ImplTraitInTraitFinder<'_, 'tcx> { && let hir::OpaqueTyOrigin::FnReturn(source) | hir::OpaqueTyOrigin::AsyncFn(source) = opaque.origin && source == self.fn_def_id { - let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, depth| { - if let ty::ReLateBound(index, bv) = re.kind() { - if depth != ty::INNERMOST { - return tcx.mk_re_error_with_message( - DUMMY_SP, - "we shouldn't walk non-predicate binders with `impl Trait`...", - ); - } - tcx.mk_re_late_bound(index.shifted_out_to_binder(self.depth), bv) - } else { - re + let opaque_ty = tcx.fold_regions(unshifted_opaque_ty, |re, _depth| { + match re.kind() { + ty::ReEarlyBound(_) | ty::ReFree(_) | ty::ReError(_) => re, + r => bug!("unexpected region: {r:?}"), } }); for (bound, bound_span) in tcx diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs index 9fe0c07814ed8..41547dd2a754d 100644 --- a/compiler/rustc_hir_analysis/src/collect.rs +++ b/compiler/rustc_hir_analysis/src/collect.rs @@ -386,8 +386,10 @@ impl<'tcx> AstConv<'tcx> for ItemCtxt<'tcx> { fn ct_infer(&self, ty: Ty<'tcx>, _: Option<&ty::GenericParamDef>, span: Span) -> Const<'tcx> { let ty = self.tcx.fold_regions(ty, |r, _| match *r { - ty::ReErased => self.tcx.lifetimes.re_static, - _ => r, + // This is never reached in practice. If it ever is reached, + // `ReErased` should be changed to `ReStatic`, and any other region + // left alone. + r => bug!("unexpected region: {r:?}"), }); self.tcx().const_error_with_message(ty, span, "bad placeholder constant") } diff --git a/compiler/rustc_middle/src/ty/subst.rs b/compiler/rustc_middle/src/ty/subst.rs index 63b2acdbe4e5d..d05d3e2d3dcf5 100644 --- a/compiler/rustc_middle/src/ty/subst.rs +++ b/compiler/rustc_middle/src/ty/subst.rs @@ -829,7 +829,13 @@ impl<'a, 'tcx> TypeFolder> for SubstFolder<'a, 'tcx> { None => region_param_out_of_range(data, self.substs), } } - _ => r, + ty::ReLateBound(..) + | ty::ReFree(_) + | ty::ReStatic + | ty::RePlaceholder(_) + | ty::ReErased + | ty::ReError(_) => r, + ty::ReVar(_) => bug!("unexpected region: {r:?}"), } } diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs index 1a566e87dc8e3..996dc329dcb9b 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs @@ -91,14 +91,15 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>( ) -> ty::Binder<'tcx, Ty<'tcx>> { debug_assert!(!ty.has_late_bound_regions()); let mut counter = 0; - let ty = tcx.fold_regions(ty, |mut r, current_depth| { - if let ty::ReErased = r.kind() { + let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() { + ty::ReErased => { let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon(None) }; counter += 1; - r = tcx.mk_re_late_bound(current_depth, br); + tcx.mk_re_late_bound(current_depth, br) } - r + // All free regions should be erased here. + r => bug!("unexpected region: {r:?}"), }); let bound_vars = tcx.mk_bound_variable_kinds_from_iter( (0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))), diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 081e4d7cfa47d..af61ca0c29f44 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -3006,16 +3006,16 @@ fn bind_generator_hidden_types_above<'tcx>( // Only remap erased regions if we use them. if considering_regions { - ty = tcx.fold_regions(ty, |mut r, current_depth| { - if let ty::ReErased = r.kind() { + ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() { + ty::ReErased => { let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon(None), }; counter += 1; - r = tcx.mk_re_late_bound(current_depth, br); + tcx.mk_re_late_bound(current_depth, br) } - r + r => bug!("unexpected region: {r:?}"), }) } diff --git a/library/core/src/iter/adapters/flatten.rs b/library/core/src/iter/adapters/flatten.rs index e0308e3360f45..7217e8f2a8ef6 100644 --- a/library/core/src/iter/adapters/flatten.rs +++ b/library/core/src/iter/adapters/flatten.rs @@ -136,26 +136,12 @@ where } #[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl TrustedLen for FlatMap +unsafe impl TrustedLen for FlatMap where - I: TrustedLen, - F: FnMut(I::Item) -> [T; N], -{ -} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap -where - I: TrustedLen, - F: FnMut(I::Item) -> &'a [T; N], -{ -} - -#[unstable(feature = "trusted_len", issue = "37572")] -unsafe impl<'a, T, I, F, const N: usize> TrustedLen for FlatMap -where - I: TrustedLen, - F: FnMut(I::Item) -> &'a mut [T; N], + I: Iterator, + U: IntoIterator, + F: FnMut(I::Item) -> U, + FlattenCompat, ::IntoIter>: TrustedLen, { } @@ -298,8 +284,8 @@ where #[unstable(feature = "trusted_len", issue = "37572")] unsafe impl TrustedLen for Flatten where - I: TrustedLen, - ::Item: TrustedConstSize, + I: Iterator, + FlattenCompat::IntoIter>: TrustedLen, { } @@ -660,6 +646,27 @@ where } } +unsafe impl TrustedLen + for FlattenCompat::IntoIter> +where + I: TrustedLen, +{ +} + +unsafe impl<'a, const N: usize, I, T> TrustedLen + for FlattenCompat::IntoIter> +where + I: TrustedLen, +{ +} + +unsafe impl<'a, const N: usize, I, T> TrustedLen + for FlattenCompat::IntoIter> +where + I: TrustedLen, +{ +} + trait ConstSizeIntoIterator: IntoIterator { // FIXME(#31844): convert to an associated const once specialization supports that fn size() -> Option; @@ -696,19 +703,6 @@ impl ConstSizeIntoIterator for &mut [T; N] { } } -#[doc(hidden)] -#[unstable(feature = "std_internals", issue = "none")] -// FIXME(#20400): Instead of this helper trait there should be multiple impl TrustedLen for Flatten<> -// blocks with different bounds on Iterator::Item but the compiler erroneously considers them overlapping -pub unsafe trait TrustedConstSize: IntoIterator {} - -#[unstable(feature = "std_internals", issue = "none")] -unsafe impl TrustedConstSize for [T; N] {} -#[unstable(feature = "std_internals", issue = "none")] -unsafe impl TrustedConstSize for &'_ [T; N] {} -#[unstable(feature = "std_internals", issue = "none")] -unsafe impl TrustedConstSize for &'_ mut [T; N] {} - #[inline] fn and_then_or_clear(opt: &mut Option, f: impl FnOnce(&mut T) -> Option) -> Option { let x = f(opt.as_mut()?); diff --git a/src/doc/rustdoc/src/SUMMARY.md b/src/doc/rustdoc/src/SUMMARY.md index 747cc629ba44b..b512135d92770 100644 --- a/src/doc/rustdoc/src/SUMMARY.md +++ b/src/doc/rustdoc/src/SUMMARY.md @@ -3,6 +3,7 @@ - [What is rustdoc?](what-is-rustdoc.md) - [Command-line arguments](command-line-arguments.md) - [How to read rustdoc output](how-to-read-rustdoc.md) + - [In-doc settings](read-documentation/in-doc-settings.md) - [How to write documentation](how-to-write-documentation.md) - [What to include (and exclude)](write-documentation/what-to-include.md) - [The `#[doc]` attribute](write-documentation/the-doc-attribute.md) diff --git a/src/doc/rustdoc/src/how-to-read-rustdoc.md b/src/doc/rustdoc/src/how-to-read-rustdoc.md index 56342f65d9998..21ce9a38b09d6 100644 --- a/src/doc/rustdoc/src/how-to-read-rustdoc.md +++ b/src/doc/rustdoc/src/how-to-read-rustdoc.md @@ -68,7 +68,7 @@ Typing in the search bar instantly searches the available documentation for the string entered with a fuzzy matching algorithm that is tolerant of minor typos. -By default, the search results give are "In Names", +By default, the search results given are "In Names", meaning that the fuzzy match is made against the names of items. Matching names are shown on the left, and the first few words of their descriptions are given on the right. @@ -105,11 +105,6 @@ will match these queries: But it *does not* match `Result` or `Result>`. -### Changing displayed theme - -You can change the displayed theme by opening the settings menu (the gear -icon in the upper right) and then pick a new one from there. - ### Shortcuts Pressing `S` while focused elsewhere on the page will move focus to the diff --git a/src/doc/rustdoc/src/images/collapsed-long-item.png b/src/doc/rustdoc/src/images/collapsed-long-item.png new file mode 100644 index 0000000000000..c382870c64a65 Binary files /dev/null and b/src/doc/rustdoc/src/images/collapsed-long-item.png differ diff --git a/src/doc/rustdoc/src/images/collapsed-trait-impls.png b/src/doc/rustdoc/src/images/collapsed-trait-impls.png new file mode 100644 index 0000000000000..f685656e09a9c Binary files /dev/null and b/src/doc/rustdoc/src/images/collapsed-trait-impls.png differ diff --git a/src/doc/rustdoc/src/read-documentation/in-doc-settings.md b/src/doc/rustdoc/src/read-documentation/in-doc-settings.md new file mode 100644 index 0000000000000..12928a4f36926 --- /dev/null +++ b/src/doc/rustdoc/src/read-documentation/in-doc-settings.md @@ -0,0 +1,64 @@ +# Rustdoc in-doc settings + +Rustdoc's HTML output includes a settings menu, and this chapter describes what +each setting in this menu does. + +It can be accessed by clicking on the gear button +() in the upper right. + +## Changing displayed theme + +It is possible to change the theme. If you pick the "system preference", you +will be able to see two new sub-menus: "Preferred light theme" and "Preferred +dark theme". It means that if your system preference is set to "light", then +rustdoc will use the theme you selected in "Preferred light theme". + +## Auto-hide item contents for large items + +If the type definition contains more than 12 items, and this setting is enabled, +it'll collapse them by default. You can see them by clicking on the `[+]` button +to expand them. + +A good example of this setting in use can be seen in the +[`Iterator`](https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html) doc +page: + +![Collapsed long item](../images/collapsed-long-item.png) + +## Auto-hide item methods' documentation + +If enabled, this setting will collapse all trait implementations blocks. It is +convenient if you just want an overview of all the methods available. You can +still see a method's documentation by expanding it. + +## Auto-hide trait implementation documentation + +If enabled, this setting will collapse all trait implementations blocks (you can +see them in the "Trait Implementations" section). It is convenient if you just +want an overview of all the trait implemented on a type. You can still see +a trait implementation's associated items by expanding it. + +Example: + +![Collapsed trait implementations](../images/collapsed-trait-impls.png) + +## Directly go to item in search if there is only one result + +If this setting is enabled, you will directly be taken to the result page if +your search only returned one element. Useful if you know exactly what you're +looking for and want to be taken there directly and not waste time selecting the +only search result. + +## Show line numbers on code examples + +If enabled, this setting will add line numbers to the code examples in the +documentation. It provides a visual aide for the code reading. + +## Disable keyboard shortcuts + +If this setting is enabled, the keyboard shortcuts will be disabled. It's useful +in case some of these shortcuts are already used by a web extension you're +using. + +To see the full list of the rustdoc keyboard shortcuts, you can open the help +menu (the button with the question mark on the left of the setting menu button). diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index eeee12a431065..1b622905e1adb 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -741,8 +741,10 @@ impl<'a, 'tcx> TypeFolder> for RegionReplacer<'a, 'tcx> { fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> { match *r { + // These are the regions that can be seen in the AST. ty::ReVar(vid) => self.vid_to_region.get(&vid).cloned().unwrap_or(r), - _ => r, + ty::ReEarlyBound(_) | ty::ReStatic | ty::ReLateBound(..) | ty::ReError(_) => r, + r => bug!("unexpected region: {r:?}"), } } } diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index daf10e5b88a83..d71098ad89da0 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -679,6 +679,10 @@ pub(crate) fn make_test( // parse the source, but only has false positives, not false // negatives. if s.contains(crate_name) { + // rustdoc implicitly inserts an `extern crate` item for the own crate + // which may be unused, so we need to allow the lint. + prog.push_str(&format!("#[allow(unused_extern_crates)]\n")); + prog.push_str(&format!("extern crate r#{crate_name};\n")); line_offset += 1; } diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index 360d2259ea3d2..a30fe28f94f99 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -38,6 +38,7 @@ fn make_test_crate_name() { let input = "use asdf::qwop; assert_eq!(2+2, 4);"; let expected = "#![allow(unused)] +#[allow(unused_extern_crates)] extern crate r#asdf; fn main() { use asdf::qwop; @@ -128,6 +129,7 @@ fn make_test_opts_attrs() { let input = "use asdf::qwop; assert_eq!(2+2, 4);"; let expected = "#![feature(sick_rad)] +#[allow(unused_extern_crates)] extern crate r#asdf; fn main() { use asdf::qwop; @@ -141,6 +143,7 @@ assert_eq!(2+2, 4); opts.attrs.push("feature(hella_dope)".to_string()); let expected = "#![feature(sick_rad)] #![feature(hella_dope)] +#[allow(unused_extern_crates)] extern crate r#asdf; fn main() { use asdf::qwop; @@ -236,6 +239,7 @@ assert_eq!(asdf::foo, 4);"; let expected = "#![allow(unused)] extern crate hella_qwop; +#[allow(unused_extern_crates)] extern crate r#asdf; fn main() { assert_eq!(asdf::foo, 4); diff --git a/tests/rustdoc/playground-arg.rs b/tests/rustdoc/playground-arg.rs index f3811fe0b0ad1..2542ed657c1a7 100644 --- a/tests/rustdoc/playground-arg.rs +++ b/tests/rustdoc/playground-arg.rs @@ -10,4 +10,4 @@ pub fn dummy() {} // ensure that `extern crate foo;` was inserted into code snips automatically: -// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0Ause+foo::dummy;%0Adummy();%0A%7D&edition=2015"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0A%23%5Ballow(unused_extern_crates)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0Ause+foo::dummy;%0Adummy();%0A%7D&edition=2015"]' "Run" diff --git a/tests/ui/inference/issue-70082.rs b/tests/ui/inference/issue-70082.rs new file mode 100644 index 0000000000000..d54d0a1a48a2d --- /dev/null +++ b/tests/ui/inference/issue-70082.rs @@ -0,0 +1,10 @@ +fn main() { + // this closure is fine, and should not get any error annotations + let em = |v: f64| -> f64 { v }; + + let x: f64 = em(1i16.into()); + + let y: f64 = 0.01f64 * 1i16.into(); + //~^ ERROR type annotations needed + //~| HELP try using a fully qualified path +} diff --git a/tests/ui/inference/issue-70082.stderr b/tests/ui/inference/issue-70082.stderr new file mode 100644 index 0000000000000..47229a5fee14d --- /dev/null +++ b/tests/ui/inference/issue-70082.stderr @@ -0,0 +1,17 @@ +error[E0284]: type annotations needed + --> $DIR/issue-70082.rs:7:33 + | +LL | let y: f64 = 0.01f64 * 1i16.into(); + | - ^^^^ + | | + | type must be known at this point + | + = note: cannot satisfy `>::Output == f64` +help: try using a fully qualified path to specify the expected types + | +LL | let y: f64 = 0.01f64 * >::into(1i16); + | +++++++++++++++++++++++ ~ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0284`.