From 02ffe9ef0101cb7b0540ca6195d63442ad3df5ec Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 6 Dec 2020 17:56:01 -0500 Subject: [PATCH] Fix injected errors when running doctests on a crate named after a keyword Unfortunately, this can't currently be tested. The problem is that we need the file to be compiled first to then be used as dependency, which cannot be done currently unfortunately in the rustdoc test suites. Example: ```rust // name this file "foo.rs" /// ``` /// let x = foo::foo(); /// ``` pub fn foo() {} ``` If you run `rustdoc --test foo.rs`, you'll get: ``` running 1 test test foo.rs - foo (line 1) ... FAILED failures: ---- foo.rs - foo (line 1) stdout ---- error[E0463]: can't find crate for `foo` --> foo.rs:0:1 | 2 | extern crate foo; | ^^^^^^^^^^^^^^^^^ can't find crate ``` If a test were possible, it would look something like ````rust #![crate_name = "mod"] #![crate_type = "lib"] //! ``` //! // NOTE: requires that the literal string 'mod' appears in the doctest for //! // the bug to appear //! assert_eq!(1, 1); //! ``` ```` --- src/librustdoc/doctest.rs | 7 +++++-- src/librustdoc/doctest/tests.rs | 8 ++++---- src/test/rustdoc/playground-arg.rs | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index eecfd337cdf84..fb4774ae19246 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -546,9 +546,12 @@ crate fn make_test( // compiler. if !already_has_extern_crate && !opts.no_crate_inject && cratename != Some("std") { if let Some(cratename) = cratename { - // Make sure its actually used if not included. + // Don't inject `extern crate` if the crate is never used. + // NOTE: this is terribly inaccurate because it doesn't actually + // parse the source, but only has false positives, not false + // negatives. if s.contains(cratename) { - prog.push_str(&format!("extern crate {};\n", cratename)); + prog.push_str(&format!("extern crate r#{};\n", cratename)); line_offset += 1; } } diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs index 465b2b1d69b34..c49e45c0e25a0 100644 --- a/src/librustdoc/doctest/tests.rs +++ b/src/librustdoc/doctest/tests.rs @@ -38,7 +38,7 @@ fn make_test_crate_name() { let input = "use asdf::qwop; assert_eq!(2+2, 4);"; let expected = "#![allow(unused)] -extern crate asdf; +extern crate r#asdf; fn main() { use asdf::qwop; assert_eq!(2+2, 4); @@ -128,7 +128,7 @@ fn make_test_opts_attrs() { let input = "use asdf::qwop; assert_eq!(2+2, 4);"; let expected = "#![feature(sick_rad)] -extern crate asdf; +extern crate r#asdf; fn main() { use asdf::qwop; assert_eq!(2+2, 4); @@ -141,7 +141,7 @@ assert_eq!(2+2, 4); opts.attrs.push("feature(hella_dope)".to_string()); let expected = "#![feature(sick_rad)] #![feature(hella_dope)] -extern crate asdf; +extern crate r#asdf; fn main() { use asdf::qwop; assert_eq!(2+2, 4); @@ -250,7 +250,7 @@ assert_eq!(asdf::foo, 4);"; let expected = "#![allow(unused)] extern crate hella_qwop; -extern crate asdf; +extern crate r#asdf; fn main() { assert_eq!(asdf::foo, 4); }" diff --git a/src/test/rustdoc/playground-arg.rs b/src/test/rustdoc/playground-arg.rs index 018716ad45af3..dbe2297f81887 100644 --- a/src/test/rustdoc/playground-arg.rs +++ b/src/test/rustdoc/playground-arg.rs @@ -11,4 +11,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%20crate%20foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D&edition=2015"]' "Run" +// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0Aextern%20crate%20r%23foo%3B%0Afn%20main()%20%7B%0Ause%20foo%3A%3Adummy%3B%0Adummy()%3B%0A%7D&edition=2015"]' "Run"