Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 33 additions & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2972,8 +2972,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// `ExprKind::DropTemps` is semantically irrelevant for these suggestions.
let expr = expr.peel_drop_temps();

match (&expr.kind, expected.kind(), checked_ty.kind()) {
// Handle call arguments that need another shared or mutable reference, such as
// `&T` to `&&T` or `&T` to `&mut &T`.
// Keep ordinary `T` to `&T` cases on later path so its more
// specific suggestions, such as `Option::as_ref()`, are preserved.
(_, &ty::Ref(_, exp, mutability), _)
if exp.is_ref()
&& matches!(
self.tcx.parent_hir_node(expr.hir_id),
hir::Node::Expr(hir::Expr {
kind:
hir::ExprKind::Call(_, args)
| hir::ExprKind::MethodCall(_, _, args, _),
..
}) if args.iter().any(|arg| arg.hir_id == expr.hir_id)
)
&& self.can_eq(self.param_env, exp, checked_ty) =>
{
let borrow = mutability.ref_prefix_str();
let sugg = if expr_needs_parens(expr) {
vec![
(sp.shrink_to_lo(), format!("{borrow}(")),
(sp.shrink_to_hi(), ")".to_string()),
]
} else {
vec![(sp.shrink_to_lo(), borrow.to_string())]
};
return Some((
sugg,
format!("consider {}borrowing here", mutability.mutably_str()),
Applicability::MachineApplicable,
false,
));
}
(_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (exp.kind(), check.kind()) {
(&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => {
if let hir::ExprKind::Lit(_) = expr.kind
Expand Down
8 changes: 8 additions & 0 deletions src/etc/htmldocck.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,8 +624,16 @@ def check_command(c, cache):

def check(target, commands):
cache = CachedFiles(target)
run_commands = 0
for c in commands:
check_command(c, cache)
run_commands += 1
if run_commands == 0 and os.environ.get("IS_RMAKE") is None:
stderr(
"\nNo check, move this file in `rustdoc-ui` testsuite if you want to check "
+ "it doesn't crash"
)
raise SystemExit(1)


if __name__ == "__main__":
Expand Down
9 changes: 9 additions & 0 deletions src/tools/compiletest/src/runtest/rustdoc.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,19 @@
use super::{DocKind, TestCx, remove_and_create_dir_all};
use crate::util::ArgFileCommand;

fn has_test_flag(flags: &[String]) -> bool {
flags.iter().any(|s| s == "--test")
}

impl TestCx<'_> {
pub(super) fn run_rustdoc_html_test(&self) {
assert!(self.variant.revision.is_none(), "revisions not supported in this test suite");

if has_test_flag(&self.props.compile_flags) || has_test_flag(&self.props.doc_flags) {
panic!(
"If you want to check `--test`, put this test into `rustdoc-ui` testsuite instead",
);
}
let out_dir = self.output_base_dir();
remove_and_create_dir_all(&out_dir).unwrap_or_else(|e| {
panic!("failed to remove and recreate output directory `{out_dir}`: {e}")
Expand Down
1 change: 1 addition & 0 deletions src/tools/run-make-support/src/external_deps/htmldocck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ use crate::source_root;
pub fn htmldocck() -> Command {
let mut python = python_command();
python.arg(source_root().join("src/etc/htmldocck.py"));
python.env("IS_RMAKE", "1");
python
}
9 changes: 9 additions & 0 deletions tests/rustdoc-gui/decl-macro-in-sidebar.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// This test ensures that the `foo` decl macro is present in the module sidebar.
// Because these items are not generated into the HTML, we can't make them a `rustdoc-html`
// test, so here we go...

go-to: "file://" + |DOC_PATH| + "/test_docs/details/index.html"
assert-text: (
'//*[@id="rustdoc-modnav"]/ul[@class="block macro"]//a[@href="../macro.decl_macro.html"]',
"decl_macro",
)
5 changes: 5 additions & 0 deletions tests/rustdoc-gui/src/test_docs/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#![feature(macro_derive)]
#![feature(negative_impls)]
#![feature(doc_notable_trait)]
#![feature(decl_macro)]

/*!
Enable the feature <span class="stab portability"><code>some-feature</code></span> to enjoy
Expand Down Expand Up @@ -822,3 +823,7 @@ pub mod notable {
pub struct Wrapper;
impl Labeled for Wrapper {}
}

pub macro decl_macro {
() => { "bar" }
}
14 changes: 7 additions & 7 deletions tests/rustdoc-html/doc-cfg/extern-items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
#![feature(doc_cfg)]
#![crate_name = "foo"]

//@has 'foo/index.html'
//@count - '//*[@class="stab portability"]' 2
//@has - '//*[@class="stab portability"]' 'Non-banana'
//@ has 'foo/index.html'
//@ count - '//*[@class="stab portability"]' 2
//@ has - '//*[@class="stab portability"]' 'Non-banana'

//@has 'foo/fn.doc_cfg_doesnt_work.html'
//@has - '//*[@class="stab portability"]' 'Available on non-crate feature banana only.'
//@ has 'foo/fn.doc_cfg_doesnt_work.html'
//@ has - '//*[@class="stab portability"]' 'Available on non-crate feature banana only.'

//@has 'foo/fn.doc_cfg_works.html'
//@has - '//*[@class="stab portability"]' 'Available on non-crate feature banana only.'
//@ has 'foo/fn.doc_cfg_works.html'
//@ has - '//*[@class="stab portability"]' 'Available on non-crate feature banana only.'

unsafe extern "C" {
#[cfg(not(feature = "banana"))]
Expand Down
4 changes: 2 additions & 2 deletions tests/rustdoc-html/doc-cfg/impl-foreign-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#![feature(doc_cfg)]
#![crate_name = "foo"]

//@has 'foo/trait.Blob.html'
//@has - '//*[@id="impl-Blob-for-Box%3CR%3E"]//*[@class="stab portability"]' 'Available on non-crate feature alloc only.'
//@ has 'foo/trait.Blob.html'
//@ has - '//*[@id="impl-Blob-for-Box%3CR%3E"]//*[@class="stab portability"]' 'Available on non-crate feature alloc only.'

pub trait Blob {}

Expand Down
12 changes: 6 additions & 6 deletions tests/rustdoc-html/doc-cfg/reexports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,17 @@
#![feature(doc_cfg)]
#![crate_name = "foo"]

//@has 'foo/struct.FlatBanana.html'
//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature banana and non-crate feature yoyo only.'
//@ has 'foo/struct.FlatBanana.html'
//@ has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature banana and non-crate feature yoyo only.'

//@has 'foo/struct.SubBanana.html'
//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana and non-crate feature yoyo only.'
//@ has 'foo/struct.SubBanana.html'
//@ has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana and non-crate feature yoyo only.'

#[cfg(not(feature = "yoyo"))]
pub use self::banana::*;

//@has 'foo/struct.Yolo.html'
//@has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana only.'
//@ has 'foo/struct.Yolo.html'
//@ has - '//*[@class="item-info"]/*[@class="stab portability"]' 'Available on non-crate feature ananas and non-crate feature banana only.'
pub use self::banana::SubBanana as Yolo;

#[cfg(not(feature = "banana"))]
Expand Down
46 changes: 23 additions & 23 deletions tests/rustdoc-html/doc-cfg/trait-impls-manual.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,36 +22,36 @@ pub trait Foo {

pub struct X;

//@has 'foo/struct.X.html'
//@count - '//*[@id="impl-Bob-for-X"]' 1
//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0
//@count - '//*[@id="impl-Trait-for-X"]' 1
//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0
//@ has 'foo/struct.X.html'
//@ count - '//*[@id="impl-Bob-for-X"]' 1
//@ count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 1
//@ count - '//*[@id="impl-Trait-for-X"]' 1
//@ count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 1

// If you need to update this XPath, in particular `item-info`, update all
// the others in this file.
//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1
//@ count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1

//@has 'foo/trait.Trait.html'
//@count - '//*[@id="impl-Trait-for-X"]' 1
//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0
//@ has 'foo/trait.Trait.html'
//@ count - '//*[@id="impl-Trait-for-X"]' 1
//@ count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 1
#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))]
#[doc(auto_cfg(hide(target_arch, values("wasm32"))))]
mod imp {
impl super::Trait for super::X { fn f(&self) {} }
}

//@has 'foo/trait.Bob.html'
//@count - '//*[@id="impl-Bob-for-X"]' 1
//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0
//@ has 'foo/trait.Bob.html'
//@ count - '//*[@id="impl-Bob-for-X"]' 1
//@ count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 1
#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))]
#[doc(auto_cfg = false)]
mod imp2 {
impl super::Bob for super::X { fn bob(&self) {} }
}

//@has 'foo/trait.Foo.html'
//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1
//@ has 'foo/trait.Foo.html'
//@ count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1
// We use this to force xpath tests to be updated if `item-info` class is changed.
#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))]
mod imp3 {
Expand All @@ -60,9 +60,9 @@ mod imp3 {

pub struct Y;

//@has 'foo/struct.Y.html'
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0
//@ has 'foo/struct.Y.html'
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]' 1
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]/*[@class="item-info"]' 0
#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))]
#[doc(auto_cfg(hide(target_arch, values("wasm32"))))]
mod imp4 {
Expand All @@ -71,9 +71,9 @@ mod imp4 {

pub struct Z;

//@has 'foo/struct.Z.html'
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0
//@ has 'foo/struct.Z.html'
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]' 1
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]/*[@class="item-info"]' 0
#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))]
#[doc(auto_cfg = false)]
mod imp5 {
Expand All @@ -83,9 +83,9 @@ mod imp5 {
// The "witness" which has the item info.
pub struct W;

//@has 'foo/struct.W.html'
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 1
//@ has 'foo/struct.W.html'
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]' 1
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]/*[@class="item-info"]' 1
#[doc(cfg(any(target_pointer_width = "64", target_arch = "wasm32")))]
mod imp6 {
impl super::W { pub fn plain_auto() {} }
Expand Down
49 changes: 26 additions & 23 deletions tests/rustdoc-html/doc-cfg/trait-impls.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// This test ensures that `doc_cfg` feature is working as expected on trait impls.
// Regression test for <https://github.com/rust-lang/rust/issues/153655>.

//@ only-linux
//@ only-x86_64

#![feature(doc_cfg)]
#![doc(auto_cfg(hide(
target_pointer_width, values("64"),
Expand All @@ -22,36 +25,36 @@ pub trait Foo {

pub struct X;

//@has 'foo/struct.X.html'
//@count - '//*[@id="impl-Bob-for-X"]' 1
//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0
//@count - '//*[@id="impl-Trait-for-X"]' 1
//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0
//@ has 'foo/struct.X.html'
//@ count - '//*[@id="impl-Bob-for-X"]' 1
//@ count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0
//@ count - '//*[@id="impl-Trait-for-X"]' 1
//@ count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0

// If you need to update this XPath, in particular `item-info`, update all
// the others in this file.
//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1
//@ count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1

//@has 'foo/trait.Trait.html'
//@count - '//*[@id="impl-Trait-for-X"]' 1
//@count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0
//@ has 'foo/trait.Trait.html'
//@ count - '//*[@id="impl-Trait-for-X"]' 1
//@ count - '//*[@id="impl-Trait-for-X"]/*[@class="item-info"]' 0
#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))]
#[doc(auto_cfg(hide(target_arch, values("wasm32"))))]
mod imp {
impl super::Trait for super::X { fn f(&self) {} }
}

//@has 'foo/trait.Bob.html'
//@count - '//*[@id="impl-Bob-for-X"]' 1
//@count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0
//@ has 'foo/trait.Bob.html'
//@ count - '//*[@id="impl-Bob-for-X"]' 1
//@ count - '//*[@id="impl-Bob-for-X"]/*[@class="item-info"]' 0
#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))]
#[doc(auto_cfg = false)]
mod imp2 {
impl super::Bob for super::X { fn bob(&self) {} }
}

//@has 'foo/trait.Foo.html'
//@count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1
//@ has 'foo/trait.Foo.html'
//@ count - '//*[@id="impl-Foo-for-X"]/*[@class="item-info"]' 1
// We use this to force xpath tests to be updated if `item-info` class is changed.
#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))]
mod imp3 {
Expand All @@ -60,9 +63,9 @@ mod imp3 {

pub struct Y;

//@has 'foo/struct.Y.html'
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0
//@ has 'foo/struct.Y.html'
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]' 1
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]/*[@class="item-info"]' 0
#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))]
#[doc(auto_cfg(hide(target_arch, values("wasm32"))))]
mod imp4 {
Expand All @@ -71,9 +74,9 @@ mod imp4 {

pub struct Z;

//@has 'foo/struct.Z.html'
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 0
//@ has 'foo/struct.Z.html'
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]' 1
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]/*[@class="item-info"]' 0
#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))]
#[doc(auto_cfg = false)]
mod imp5 {
Expand All @@ -83,9 +86,9 @@ mod imp5 {
// The "witness" which has the item info.
pub struct W;

//@has 'foo/struct.W.html'
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]' 1
//@count - '//*[@id="implementations-list"]/*[@class="impl-items"]/*[@class="item-info"]' 1
//@ has 'foo/struct.W.html'
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]' 1
//@ count - '//*[@id="implementations-list"]//*[@class="impl-items"]//*[@class="item-info"]' 1
#[cfg(any(target_pointer_width = "64", target_arch = "wasm32"))]
mod imp6 {
impl super::W { pub fn plain_auto() {} }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
//@ has foo/impls/bar/trait.Bar.html
//@ has - '//h3[@class="code-header"]' 'impl Bar for Foo'
//@ count - '//*[@class="struct"]' 1
#[path = "auxiliary/impls.rs"]
pub mod impls;

#[doc(inline)]
Expand Down
15 changes: 0 additions & 15 deletions tests/rustdoc-html/macro/decl_macro-sidebar.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Test for https://github.com/rust-lang/rust/issues/48463 issue.

//@ check-pass

use std::any::Any;
use std::ops::Deref;

Expand Down
Loading
Loading