From dc17f38e041e6bde95c6f6c5c6170dbb3917d51e Mon Sep 17 00:00:00 2001 From: Mazdak Farrokhzad Date: Tue, 28 Jan 2020 01:58:14 +0100 Subject: [PATCH 1/7] check_unsafety: more code reuse --- src/librustc_mir/transform/check_unsafety.rs | 57 +++++++------------- 1 file changed, 18 insertions(+), 39 deletions(-) diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 59d370abc71c5..343488b2f9500 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -148,16 +148,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast"); match (cast_in, cast_out) { (CastTy::Ptr(_), CastTy::Int(_)) | (CastTy::FnPtr, CastTy::Int(_)) => { - self.register_violations( - &[UnsafetyViolation { - source_info: self.source_info, - description: Symbol::intern("cast of pointer to int"), - details: Symbol::intern( - "casting pointers to integers in constants", - ), - kind: UnsafetyViolationKind::General, - }], - &[], + self.require_unsafe( + "cast of pointer to int", + "casting pointers to integers in constants", + UnsafetyViolationKind::General, ); } _ => {} @@ -171,14 +165,10 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { if self.const_context && self.tcx.features().const_compare_raw_pointers => { if let ty::RawPtr(_) | ty::FnPtr(..) = lhs.ty(self.body, self.tcx).kind { - self.register_violations( - &[UnsafetyViolation { - source_info: self.source_info, - description: Symbol::intern("pointer operation"), - details: Symbol::intern("operations on pointers in constants"), - kind: UnsafetyViolationKind::General, - }], - &[], + self.require_unsafe( + "pointer operation", + "operations on pointers in constants", + UnsafetyViolationKind::General, ); } } @@ -199,18 +189,12 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> { .as_ref() .assert_crate_local() .lint_root; - self.register_violations( - &[UnsafetyViolation { - source_info, - description: Symbol::intern("borrow of packed field"), - details: Symbol::intern( - "fields of packed structs might be misaligned: dereferencing a \ - misaligned pointer or even just creating a misaligned reference \ - is undefined behavior", - ), - kind: UnsafetyViolationKind::BorrowPacked(lint_root), - }], - &[], + self.require_unsafe( + "borrow of packed field", + "fields of packed structs might be misaligned: dereferencing a \ + misaligned pointer or even just creating a misaligned reference \ + is undefined behavior", + UnsafetyViolationKind::BorrowPacked(lint_root), ); } } @@ -435,15 +419,10 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> { the field can be changed to invalid values", ) }; - let source_info = self.source_info; - self.register_violations( - &[UnsafetyViolation { - source_info, - description: Symbol::intern(description), - details: Symbol::intern(details), - kind: UnsafetyViolationKind::GeneralAndConstFn, - }], - &[], + self.require_unsafe( + description, + details, + UnsafetyViolationKind::GeneralAndConstFn, ); } }, From 50ed6cbf9836a48c938e74bb28501ffbbe59585e Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Thu, 30 Jan 2020 10:07:36 +0900 Subject: [PATCH 2/7] Fix typo. --- src/libstd/sys/unix/thread.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index a5b34eeec289e..58b4839f9028f 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -426,7 +426,7 @@ pub mod guard { } // glibc >= 2.15 has a __pthread_get_minstack() function that returns -// PTHREAD_STACK_MIN plus however many bytes are needed for thread-local +// PTHREAD_STACK_MIN plus how many bytes are needed for thread-local // storage. We need that information to avoid blowing up when a small stack // is created in an application with big thread-local storage requirements. // See #6233 for rationale and details. From c870ca6217038e80138b69a88b2340b62859f52b Mon Sep 17 00:00:00 2001 From: Hiroki Noda Date: Thu, 30 Jan 2020 10:31:12 +0900 Subject: [PATCH 3/7] Update --- src/libstd/sys/unix/thread.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index 58b4839f9028f..3ca778354e413 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -426,8 +426,8 @@ pub mod guard { } // glibc >= 2.15 has a __pthread_get_minstack() function that returns -// PTHREAD_STACK_MIN plus how many bytes are needed for thread-local -// storage. We need that information to avoid blowing up when a small stack +// PTHREAD_STACK_MIN plus bytes needed for thread-local storage. +// We need that information to avoid blowing up when a small stack // is created in an application with big thread-local storage requirements. // See #6233 for rationale and details. #[cfg(target_os = "linux")] From 2f575dab3030467525acae204e47f7a9a8311530 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 29 Jan 2020 13:32:37 +0100 Subject: [PATCH 4/7] Add missing links for cmp traits --- src/libcore/cmp.rs | 51 ++++++++++++++++++++++++++++------------------ 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs index 3ea4baa57b49e..e41a7afd3e223 100644 --- a/src/libcore/cmp.rs +++ b/src/libcore/cmp.rs @@ -35,7 +35,7 @@ use self::Ordering::*; /// /// This trait allows for partial equality, for types that do not have a full /// equivalence relation. For example, in floating point numbers `NaN != NaN`, -/// so floating point types implement `PartialEq` but not `Eq`. +/// so floating point types implement `PartialEq` but not [`Eq`]. /// /// Formally, the equality must be (for all `a`, `b` and `c`): /// @@ -55,12 +55,12 @@ use self::Ordering::*; /// /// ## How can I implement `PartialEq`? /// -/// PartialEq only requires the `eq` method to be implemented; `ne` is defined -/// in terms of it by default. Any manual implementation of `ne` *must* respect -/// the rule that `eq` is a strict inverse of `ne`; that is, `!(a == b)` if and +/// `PartialEq` only requires the [`eq`] method to be implemented; [`ne`] is defined +/// in terms of it by default. Any manual implementation of [`ne`] *must* respect +/// the rule that [`eq`] is a strict inverse of [`ne`]; that is, `!(a == b)` if and /// only if `a != b`. /// -/// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* agree with +/// Implementations of `PartialEq`, [`PartialOrd`], and [`Ord`] *must* agree with /// each other. It's easy to accidentally make them disagree by deriving some /// of the traits and manually implementing others. /// @@ -190,6 +190,9 @@ use self::Ordering::*; /// assert_eq!(x == y, false); /// assert_eq!(x.eq(&y), false); /// ``` +/// +/// [`eq`]: PartialEq::eq +/// [`ne`]: PartialEq::ne #[lang = "eq"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(alias = "==")] @@ -233,7 +236,7 @@ pub macro PartialEq($item:item) { /// - transitive: `a == b` and `b == c` implies `a == c`. /// /// This property cannot be checked by the compiler, and therefore `Eq` implies -/// `PartialEq`, and has no extra methods. +/// [`PartialEq`], and has no extra methods. /// /// ## Derivable /// @@ -370,6 +373,7 @@ impl Ordering { /// Chains two orderings. /// /// Returns `self` when it's not `Equal`. Otherwise returns `other`. + /// /// # Examples /// /// ``` @@ -442,10 +446,12 @@ impl Ordering { /// A helper struct for reverse ordering. /// -/// This struct is a helper to be used with functions like `Vec::sort_by_key` and +/// This struct is a helper to be used with functions like [`Vec::sort_by_key`] and /// can be used to reverse order a part of a key. /// -/// Example usage: +/// [`Vec::sort_by_key`]: ../../std/vec/struct.Vec.html#method.sort_by_key +/// +/// # Examples /// /// ``` /// use std::cmp::Reverse; @@ -506,12 +512,12 @@ impl Ord for Reverse { /// /// ## How can I implement `Ord`? /// -/// `Ord` requires that the type also be `PartialOrd` and `Eq` (which requires `PartialEq`). +/// `Ord` requires that the type also be [`PartialOrd`] and [`Eq`] (which requires [`PartialEq`]). /// -/// Then you must define an implementation for `cmp()`. You may find it useful to use -/// `cmp()` on your type's fields. +/// Then you must define an implementation for [`cmp`]. You may find it useful to use +/// [`cmp`] on your type's fields. /// -/// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* +/// Implementations of [`PartialEq`], [`PartialOrd`], and `Ord` *must* /// agree with each other. That is, `a.cmp(b) == Ordering::Equal` if /// and only if `a == b` and `Some(a.cmp(b)) == a.partial_cmp(b)` for /// all `a` and `b`. It's easy to accidentally make them disagree by @@ -548,13 +554,15 @@ impl Ord for Reverse { /// } /// } /// ``` +/// +/// [`cmp`]: Ord::cmp #[doc(alias = "<")] #[doc(alias = ">")] #[doc(alias = "<=")] #[doc(alias = ">=")] #[stable(feature = "rust1", since = "1.0.0")] pub trait Ord: Eq + PartialOrd { - /// This method returns an `Ordering` between `self` and `other`. + /// This method returns an [`Ordering`] between `self` and `other`. /// /// By convention, `self.cmp(&other)` returns the ordering matching the expression /// `self other` if true. @@ -689,20 +697,20 @@ impl PartialOrd for Ordering { /// /// ## How can I implement `PartialOrd`? /// -/// `PartialOrd` only requires implementation of the `partial_cmp` method, with the others +/// `PartialOrd` only requires implementation of the [`partial_cmp`] method, with the others /// generated from default implementations. /// /// However it remains possible to implement the others separately for types which do not have a /// total order. For example, for floating point numbers, `NaN < 0 == false` and `NaN >= 0 == /// false` (cf. IEEE 754-2008 section 5.11). /// -/// `PartialOrd` requires your type to be `PartialEq`. +/// `PartialOrd` requires your type to be [`PartialEq`]. /// -/// Implementations of `PartialEq`, `PartialOrd`, and `Ord` *must* agree with each other. It's +/// Implementations of [`PartialEq`], `PartialOrd`, and [`Ord`] *must* agree with each other. It's /// easy to accidentally make them disagree by deriving some of the traits and manually /// implementing others. /// -/// If your type is `Ord`, you can implement `partial_cmp()` by using `cmp()`: +/// If your type is [`Ord`], you can implement [`partial_cmp`] by using [`cmp`]: /// /// ``` /// use std::cmp::Ordering; @@ -733,7 +741,7 @@ impl PartialOrd for Ordering { /// } /// ``` /// -/// You may also find it useful to use `partial_cmp()` on your type's fields. Here +/// You may also find it useful to use [`partial_cmp`] on your type's fields. Here /// is an example of `Person` types who have a floating-point `height` field that /// is the only field to be used for sorting: /// @@ -768,6 +776,9 @@ impl PartialOrd for Ordering { /// assert_eq!(x < y, true); /// assert_eq!(x.lt(&y), true); /// ``` +/// +/// [`partial_cmp`]: PartialOrd::partial_cmp +/// [`cmp`]: Ord::cmp #[lang = "partial_ord"] #[stable(feature = "rust1", since = "1.0.0")] #[doc(alias = ">")] @@ -893,7 +904,7 @@ pub macro PartialOrd($item:item) { /// /// Returns the first argument if the comparison determines them to be equal. /// -/// Internally uses an alias to `Ord::min`. +/// Internally uses an alias to [`Ord::min`]. /// /// # Examples /// @@ -956,7 +967,7 @@ pub fn min_by_key K, K: Ord>(v1: T, v2: T, mut f: F) -> T { /// /// Returns the second argument if the comparison determines them to be equal. /// -/// Internally uses an alias to `Ord::max`. +/// Internally uses an alias to [`Ord::max`]. /// /// # Examples /// From db319a8fb0126b84e0a0abbac83d4e1adeca6a95 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 22 Jan 2020 11:24:32 -0500 Subject: [PATCH 5/7] suggest adding space in accidental doc comments --- src/librustc_parse/parser/stmt.rs | 21 +++++++- src/test/ui/parser/doc-comment-in-stmt.rs | 20 ++++++++ src/test/ui/parser/doc-comment-in-stmt.stderr | 50 +++++++++++++++++++ 3 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/parser/doc-comment-in-stmt.rs create mode 100644 src/test/ui/parser/doc-comment-in-stmt.stderr diff --git a/src/librustc_parse/parser/stmt.rs b/src/librustc_parse/parser/stmt.rs index a94d8228bbe85..ae8f1e4db1b38 100644 --- a/src/librustc_parse/parser/stmt.rs +++ b/src/librustc_parse/parser/stmt.rs @@ -7,13 +7,13 @@ use crate::maybe_whole; use crate::DirectoryOwnership; use rustc_errors::{Applicability, PResult}; -use rustc_span::source_map::{respan, Span}; +use rustc_span::source_map::{respan, BytePos, Span}; use rustc_span::symbol::{kw, sym, Symbol}; use syntax::ast; use syntax::ast::{AttrStyle, AttrVec, Attribute, Mac, MacStmtStyle, VisibilityKind}; use syntax::ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID}; use syntax::ptr::P; -use syntax::token; +use syntax::token::{self, TokenKind}; use syntax::util::classify; use std::mem; @@ -431,6 +431,23 @@ impl<'a> Parser<'a> { if let Err(mut e) = self.expect_one_of(&[], &[token::Semi, token::CloseDelim(token::Brace)]) { + if let TokenKind::DocComment(..) = self.token.kind { + if let Ok(snippet) = self.span_to_snippet(self.token.span) { + let sp = self.token.span; + let marker = &snippet[..3]; + let (comment_marker, doc_comment_marker) = marker.split_at(2); + + e.span_suggestion( + sp.with_hi(sp.lo() + BytePos(marker.len() as u32)), + &format!( + "add a space before `{}` to use a regular comment", + doc_comment_marker, + ), + format!("{} {}", comment_marker, doc_comment_marker), + Applicability::MaybeIncorrect, + ); + } + } e.emit(); self.recover_stmt(); // Don't complain about type errors in body tail after parse error (#57383). diff --git a/src/test/ui/parser/doc-comment-in-stmt.rs b/src/test/ui/parser/doc-comment-in-stmt.rs new file mode 100644 index 0000000000000..b02df13213f20 --- /dev/null +++ b/src/test/ui/parser/doc-comment-in-stmt.rs @@ -0,0 +1,20 @@ +fn foo() -> bool { + false + //!self.allow_ty_infer() + //~^ ERROR found doc comment +} + +fn bar() -> bool { + false + /*! bar */ //~ ERROR found doc comment +} + +fn baz() -> i32 { + 1 /** baz */ //~ ERROR found doc comment +} + +fn quux() -> i32 { + 2 /*! quux */ //~ ERROR found doc comment +} + +fn main() {} diff --git a/src/test/ui/parser/doc-comment-in-stmt.stderr b/src/test/ui/parser/doc-comment-in-stmt.stderr new file mode 100644 index 0000000000000..5d94d6fe69b59 --- /dev/null +++ b/src/test/ui/parser/doc-comment-in-stmt.stderr @@ -0,0 +1,50 @@ +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `//!self.allow_ty_infer()` + --> $DIR/doc-comment-in-stmt.rs:3:5 + | +LL | false + | - expected one of `.`, `;`, `?`, `}`, or an operator +LL | //!self.allow_ty_infer() + | ^^^^^^^^^^^^^^^^^^^^^^^^ unexpected token + | +help: add a space before `!` to use a regular comment + | +LL | // !self.allow_ty_infer() + | ^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! bar */` + --> $DIR/doc-comment-in-stmt.rs:9:5 + | +LL | false + | - expected one of `.`, `;`, `?`, `}`, or an operator +LL | /*! bar */ + | ^^^^^^^^^^ unexpected token + | +help: add a space before `!` to use a regular comment + | +LL | /* ! bar */ + | ^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/** baz */` + --> $DIR/doc-comment-in-stmt.rs:13:7 + | +LL | 1 /** baz */ + | ^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + | +help: add a space before `*` to use a regular comment + | +LL | 1 /* * baz */ + | ^^^^ + +error: expected one of `.`, `;`, `?`, `}`, or an operator, found doc comment `/*! quux */` + --> $DIR/doc-comment-in-stmt.rs:17:7 + | +LL | 2 /*! quux */ + | ^^^^^^^^^^^ expected one of `.`, `;`, `?`, `}`, or an operator + | +help: add a space before `!` to use a regular comment + | +LL | 2 /* ! quux */ + | ^^^^ + +error: aborting due to 4 previous errors + From 7632ade65bde6160c46f31495532f5beadcaa3d8 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Wed, 22 Jan 2020 10:33:46 -0500 Subject: [PATCH 6/7] clarify "incorrect issue" error --- src/libsyntax/attr/builtin.rs | 55 ++++++++++++------- .../unstable-attribute-allow-issue-0.rs | 4 +- .../unstable-attribute-allow-issue-0.stderr | 8 ++- .../stability-attribute-sanity-2.rs | 2 +- .../stability-attribute-sanity-2.stderr | 8 ++- 5 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index 6cfe4f2de1e96..1da005d70d41b 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -371,6 +371,7 @@ where let mut feature = None; let mut reason = None; let mut issue = None; + let mut issue_num = None; let mut is_soft = false; for meta in metas { if let Some(mi) = meta.meta_item() { @@ -389,6 +390,37 @@ where if !get(mi, &mut issue) { continue 'outer; } + + // These unwraps are safe because `get` ensures the meta item + // is a name/value pair string literal. + issue_num = match &*issue.unwrap().as_str() { + "none" => None, + issue => { + match issue.parse() { + Ok(num) => { + // FIXME(rossmacarthur): disallow 0 + // Disallowing this requires updates to + // some submodules + NonZeroU32::new(num) + } + Err(err) => { + struct_span_err!( + diagnostic, + mi.span, + E0545, + "`issue` must be a numeric string \ + or \"none\"", + ) + .span_label( + mi.name_value_literal().unwrap().span, + &err.to_string(), + ) + .emit(); + continue 'outer; + } + } + } + }; } sym::soft => { if !mi.is_word() { @@ -420,27 +452,8 @@ where } match (feature, reason, issue) { - (Some(feature), reason, Some(issue)) => { - let issue = match &*issue.as_str() { - "none" => None, - issue => { - if let Ok(num) = issue.parse() { - // FIXME(rossmacarthur): disallow 0 - // Disallowing this requires updates to some submodules - NonZeroU32::new(num) - } else { - struct_span_err!( - diagnostic, - attr.span, - E0545, - "incorrect 'issue'" - ) - .emit(); - continue; - } - } - }; - let level = Unstable { reason, issue, is_soft }; + (Some(feature), reason, Some(_)) => { + let level = Unstable { reason, issue: issue_num, is_soft }; if sym::unstable == meta_name { stab = Some(Stability { level, feature, rustc_depr: None }); } else { diff --git a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs index c8ad0d13a1413..7a2bf468f893a 100644 --- a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs +++ b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.rs @@ -9,5 +9,5 @@ fn unstable_issue_0() {} #[unstable(feature = "unstable_test_feature", issue = "none")] fn unstable_issue_none() {} -#[unstable(feature = "unstable_test_feature", issue = "something")] //~ ERROR incorrect 'issue' -fn unstable_issue_not_allowed() {} +#[unstable(feature = "unstable_test_feature", issue = "something")] +fn unstable_issue_not_allowed() {} //~^ ERROR `issue` must be a numeric string or "none" diff --git a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr index 10bd6f373d928..21ff12185ec5f 100644 --- a/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr +++ b/src/test/ui/feature-gate/unstable-attribute-allow-issue-0.stderr @@ -1,8 +1,10 @@ -error[E0545]: incorrect 'issue' - --> $DIR/unstable-attribute-allow-issue-0.rs:12:1 +error[E0545]: `issue` must be a numeric string or "none" + --> $DIR/unstable-attribute-allow-issue-0.rs:12:47 | LL | #[unstable(feature = "unstable_test_feature", issue = "something")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^----------- + | | + | invalid digit found in string error: aborting due to previous error diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs b/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs index 5a67ca0b0c88a..e74147ce900e8 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs +++ b/src/test/ui/stability-attribute/stability-attribute-sanity-2.rs @@ -10,7 +10,7 @@ fn f1() { } #[stable(feature = "a", sinse = "1.0.0")] //~ ERROR unknown meta item 'sinse' fn f2() { } -#[unstable(feature = "a", issue = "no")] //~ ERROR incorrect 'issue' +#[unstable(feature = "a", issue = "no")] //~ ERROR `issue` must be a numeric string or "none" fn f3() { } fn main() { } diff --git a/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr b/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr index d683d0895301f..541b94afe0f67 100644 --- a/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr +++ b/src/test/ui/stability-attribute/stability-attribute-sanity-2.stderr @@ -10,11 +10,13 @@ error[E0541]: unknown meta item 'sinse' LL | #[stable(feature = "a", sinse = "1.0.0")] | ^^^^^^^^^^^^^^^ expected one of `since`, `note` -error[E0545]: incorrect 'issue' - --> $DIR/stability-attribute-sanity-2.rs:13:1 +error[E0545]: `issue` must be a numeric string or "none" + --> $DIR/stability-attribute-sanity-2.rs:13:27 | LL | #[unstable(feature = "a", issue = "no")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^---- + | | + | invalid digit found in string error: aborting due to 3 previous errors From bfcfab630ef246c9439897c5351f54989e197a5c Mon Sep 17 00:00:00 2001 From: Oliver Middleton Date: Thu, 30 Jan 2020 21:14:39 +0000 Subject: [PATCH 7/7] Add `#![doc(html_playground_url = ...)]` to alloc crate This adds the Run button to code examples just like the core and std docs have. --- src/liballoc/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 38c6fa91cc55c..ffa4176cc7969 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -60,6 +60,7 @@ #![stable(feature = "alloc", since = "1.36.0")] #![doc( html_root_url = "https://doc.rust-lang.org/nightly/", + html_playground_url = "https://play.rust-lang.org/", issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/", test(no_crate_inject, attr(allow(unused_variables), deny(warnings))) )]