Auto merge of #86515 - JohnTitor:rollup-axzb4xh, r=JohnTitor

Rollup of 9 pull requests

Successful merges:

 - #86192 (Make OR_PATTERNS_BACK_COMPAT be a 2021 future-incompatible lint)
 - #86248 (Add a regression test for issue-85113)
 - #86274 (Spaces)
 - #86349 (Add regression test for issue #78632)
 - #86424 (rustfmt: load nested out-of-line mods correctly)
 - #86472 (Fix CI to fetch master on beta channel)
 - #86473 (Rustdoc: Account for const-unstable functions)
 - #86495 (Improve `proc_macro::{Punct, Spacing}` documentation)
 - #86503 (Fix rust.css fonts.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2021-06-21 19:36:04 +00:00
commit 406d4a9cc3
41 changed files with 432 additions and 134 deletions

View file

@ -9,7 +9,7 @@ along with any information you feel relevant to replicating the bug.
If you cannot produce a minimal reproduction case (something that would work in If you cannot produce a minimal reproduction case (something that would work in
isolation), please provide the steps or even link to a repository that causes isolation), please provide the steps or even link to a repository that causes
the problematic output to occur. the problematic output to occur.
--> -->
Given the following code: <!-- Please provide a link to play.rust-lang.org --> Given the following code: <!-- Please provide a link to play.rust-lang.org -->

View file

@ -21,7 +21,7 @@ Read ["Installation"] from [The Book].
The Rust build system uses a Python script called `x.py` to build the compiler, The Rust build system uses a Python script called `x.py` to build the compiler,
which manages the bootstrapping process. It lives in the root of the project. which manages the bootstrapping process. It lives in the root of the project.
The `x.py` command can be run directly on most systems in the following format: The `x.py` command can be run directly on most systems in the following format:
```sh ```sh
./x.py <subcommand> [flags] ./x.py <subcommand> [flags]

View file

@ -369,7 +369,7 @@ Language
-------- --------
- [You can now parameterize items such as functions, traits, and `struct`s by constant - [You can now parameterize items such as functions, traits, and `struct`s by constant
values in addition to by types and lifetimes.][79135] Also known as "const generics" values in addition to by types and lifetimes.][79135] Also known as "const generics"
E.g. you can now write the following. Note: Only values of primitive integers, E.g. you can now write the following. Note: Only values of primitive integers,
`bool`, or `char` types are currently permitted. `bool`, or `char` types are currently permitted.
```rust ```rust
struct GenericArray<T, const LENGTH: usize> { struct GenericArray<T, const LENGTH: usize> {

View file

@ -3239,4 +3239,8 @@ declare_lint! {
pub OR_PATTERNS_BACK_COMPAT, pub OR_PATTERNS_BACK_COMPAT,
Allow, Allow,
"detects usage of old versions of or-patterns", "detects usage of old versions of or-patterns",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #84869 <https://github.com/rust-lang/rust/issues/84869>",
edition: Some(Edition::Edition2021),
};
} }

View file

@ -567,8 +567,8 @@ changelog-seen = 2
# On Linux target, if crt-static is not enabled, 'no' means dynamic link to # On Linux target, if crt-static is not enabled, 'no' means dynamic link to
# `libgcc_s.so`, 'in-tree' means static link to the in-tree build of llvm libunwind # `libgcc_s.so`, 'in-tree' means static link to the in-tree build of llvm libunwind
# and 'system' means dynamic link to `libunwind.so`. If crt-static is enabled, # and 'system' means dynamic link to `libunwind.so`. If crt-static is enabled,
# the behavior is depend on the libc. On musl target, 'no' and 'in-tree' both # the behavior is depend on the libc. On musl target, 'no' and 'in-tree' both
# means static link to the in-tree build of llvm libunwind, and 'system' means # means static link to the in-tree build of llvm libunwind, and 'system' means
# static link to `libunwind.a` provided by system. Due to the limitation of glibc, # static link to `libunwind.a` provided by system. Due to the limitation of glibc,
# it must link to `libgcc_eh.a` to get a working output, and this option have no effect. # it must link to `libgcc_eh.a` to get a working output, and this option have no effect.
#llvm-libunwind = 'no' #llvm-libunwind = 'no'

View file

@ -766,7 +766,7 @@ impl fmt::Debug for Group {
} }
} }
/// An `Punct` is an single punctuation character like `+`, `-` or `#`. /// A `Punct` is a single punctuation character such as `+`, `-` or `#`.
/// ///
/// Multi-character operators like `+=` are represented as two instances of `Punct` with different /// Multi-character operators like `+=` are represented as two instances of `Punct` with different
/// forms of `Spacing` returned. /// forms of `Spacing` returned.
@ -779,16 +779,19 @@ impl !Send for Punct {}
#[stable(feature = "proc_macro_lib2", since = "1.29.0")] #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
impl !Sync for Punct {} impl !Sync for Punct {}
/// Whether an `Punct` is followed immediately by another `Punct` or /// Describes whether a `Punct` is followed immediately by another `Punct` ([`Spacing::Joint`]) or
/// followed by another token or whitespace. /// by a different token or whitespace ([`Spacing::Alone`]).
#[derive(Copy, Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[stable(feature = "proc_macro_lib2", since = "1.29.0")] #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
pub enum Spacing { pub enum Spacing {
/// e.g., `+` is `Alone` in `+ =`, `+ident` or `+()`. /// A `Punct` is not immediately followed by another `Punct`.
/// E.g. `+` is `Alone` in `+ =`, `+ident` and `+()`.
#[stable(feature = "proc_macro_lib2", since = "1.29.0")] #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Alone, Alone,
/// e.g., `+` is `Joint` in `+=` or `'#`. /// A `Punct` is immediately followed by another `Punct`.
/// Additionally, single quote `'` can join with identifiers to form lifetimes `'ident`. /// E.g. `+` is `Joint` in `+=` and `++`.
///
/// Additionally, single quote `'` can join with identifiers to form lifetimes: `'ident`.
#[stable(feature = "proc_macro_lib2", since = "1.29.0")] #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
Joint, Joint,
} }

View file

@ -31,7 +31,7 @@ mkdir "$CACHE_DIR"
# On the beta channel we'll be automatically calculating the prerelease version # On the beta channel we'll be automatically calculating the prerelease version
# via the git history, so unshallow our shallow clone from CI. # via the git history, so unshallow our shallow clone from CI.
if grep -q RUST_RELEASE_CHANNEL=beta src/ci/run.sh; then if [ "$(releaseChannel)" = "beta" ]; then
git fetch origin --unshallow beta master git fetch origin --unshallow beta master
fi fi

View file

@ -65,11 +65,7 @@ fi
# Always set the release channel for bootstrap; this is normally not important (i.e., only dist # Always set the release channel for bootstrap; this is normally not important (i.e., only dist
# builds would seem to matter) but in practice bootstrap wants to know whether we're targeting # builds would seem to matter) but in practice bootstrap wants to know whether we're targeting
# master, beta, or stable with a build to determine whether to run some checks (notably toolstate). # master, beta, or stable with a build to determine whether to run some checks (notably toolstate).
if [[ -z "${RUST_CI_OVERRIDE_RELEASE_CHANNEL+x}" ]]; then export RUST_RELEASE_CHANNEL=$(releaseChannel)
export RUST_RELEASE_CHANNEL="$(cat "${ci_dir}/channel")"
else
export RUST_RELEASE_CHANNEL="${RUST_CI_OVERRIDE_RELEASE_CHANNEL}"
fi
RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL" RUST_CONFIGURE_ARGS="$RUST_CONFIGURE_ARGS --release-channel=$RUST_RELEASE_CHANNEL"
if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then if [ "$DEPLOY$DEPLOY_ALT" = "1" ]; then

View file

@ -141,3 +141,11 @@ function ciCommandSetEnv {
exit 1 exit 1
fi fi
} }
function releaseChannel {
if [[ -z "${RUST_CI_OVERRIDE_RELEASE_CHANNEL+x}" ]]; then
cat "${ci_dir}/channel"
else
echo $RUST_CI_OVERRIDE_RELEASE_CHANNEL
fi
}

View file

@ -1,45 +1,68 @@
/* See FiraSans-LICENSE.txt for the Fira Sans license. */
@font-face { @font-face {
font-family: 'Fira Sans'; font-family: 'Fira Sans';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: local('Fira Sans'), url("FiraSans-Regular.woff") format('woff'); src: local('Fira Sans'),
url("FiraSans-Regular.woff2") format("woff2"),
url("FiraSans-Regular.woff") format('woff');
font-display: swap; font-display: swap;
} }
@font-face { @font-face {
font-family: 'Fira Sans'; font-family: 'Fira Sans';
font-style: normal; font-style: normal;
font-weight: 500; font-weight: 500;
src: local('Fira Sans Medium'), url("FiraSans-Medium.woff") format('woff'); src: local('Fira Sans Medium'),
url("FiraSans-Medium.woff2") format("woff2"),
url("FiraSans-Medium.woff") format('woff');
font-display: swap; font-display: swap;
} }
/* See SourceSerif4-LICENSE.md for the Source Serif 4 license. */
@font-face { @font-face {
font-family: 'Source Serif Pro'; font-family: 'Source Serif 4';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
src: local('Source Serif Pro'), url("SourceSerifPro-Regular.ttf.woff") format('woff'); src: local('Source Serif 4'), url("SourceSerif4-Regular.ttf.woff") format('woff');
font-display: swap; font-display: swap;
} }
@font-face { @font-face {
font-family: 'Source Serif Pro'; font-family: 'Source Serif 4';
font-style: italic; font-style: italic;
font-weight: 400; font-weight: 400;
src: url("SourceSerifPro-It.ttf.woff") format('woff'); src: local('Source Serif 4 Italic'), url("SourceSerif4-It.ttf.woff") format('woff');
font-display: swap; font-display: swap;
} }
@font-face { @font-face {
font-family: 'Source Serif Pro'; font-family: 'Source Serif 4';
font-style: normal; font-style: normal;
font-weight: 700; font-weight: 700;
src: local('Source Serif Pro Bold'), url("SourceSerifPro-Bold.ttf.woff") format('woff'); src: local('Source Serif 4 Bold'), url("SourceSerif4-Bold.ttf.woff") format('woff');
font-display: swap; font-display: swap;
} }
/* See SourceCodePro-LICENSE.txt for the Source Code Pro license. */
@font-face { @font-face {
font-family: 'Source Code Pro'; font-family: 'Source Code Pro';
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
/* Avoid using locally installed font because bad versions are in circulation: /* Avoid using locally installed font because bad versions are in circulation:
* see https://github.com/rust-lang/rust/issues/24355 */ * see https://github.com/rust-lang/rust/issues/24355 */
src: url("SourceCodePro-Regular.woff") format('woff'); src: url("SourceCodePro-Regular.ttf.woff") format('woff');
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: italic;
font-weight: 400;
src: url("SourceCodePro-It.ttf.woff") format('woff');
font-display: swap;
}
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 600;
src: url("SourceCodePro-Semibold.ttf.woff") format('woff');
font-display: swap; font-display: swap;
} }
@ -55,7 +78,7 @@ body {
background-color: white; background-color: white;
margin: 0 auto; margin: 0 auto;
padding: 0 15px; padding: 0 15px;
font-family: "Source Serif Pro", Georgia, Times, "Times New Roman", serif; font-family: "Source Serif 4", Georgia, Times, "Times New Roman", serif;
font-size: 18px; font-size: 18px;
color: #333; color: #333;
line-height: 1.428571429; line-height: 1.428571429;

View file

@ -9,6 +9,7 @@ use std::cell::Cell;
use std::fmt; use std::fmt;
use std::iter; use std::iter;
use rustc_attr::{ConstStability, StabilityLevel};
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
@ -1253,15 +1254,6 @@ impl PrintWithSpace for hir::Unsafety {
} }
} }
impl PrintWithSpace for hir::Constness {
fn print_with_space(&self) -> &str {
match self {
hir::Constness::Const => "const ",
hir::Constness::NotConst => "",
}
}
}
impl PrintWithSpace for hir::IsAsync { impl PrintWithSpace for hir::IsAsync {
fn print_with_space(&self) -> &str { fn print_with_space(&self) -> &str {
match self { match self {
@ -1280,6 +1272,22 @@ impl PrintWithSpace for hir::Mutability {
} }
} }
crate fn print_constness_with_space(
c: &hir::Constness,
s: Option<&ConstStability>,
) -> &'static str {
match (c, s) {
// const stable or when feature(staged_api) is not set
(
hir::Constness::Const,
Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }),
)
| (hir::Constness::Const, None) => "const ",
// const unstable or not const
_ => "",
}
}
impl clean::Import { impl clean::Import {
crate fn print<'a, 'tcx: 'a>( crate fn print<'a, 'tcx: 'a>(
&'a self, &'a self,

View file

@ -42,7 +42,7 @@ use std::str;
use std::string::ToString; use std::string::ToString;
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_attr::{Deprecation, StabilityLevel}; use rustc_attr::{ConstStability, Deprecation, StabilityLevel};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::CtorKind; use rustc_hir::def::CtorKind;
@ -61,8 +61,8 @@ use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape; use crate::html::escape::Escape;
use crate::html::format::{ use crate::html::format::{
href, print_abi_with_space, print_default_space, print_generic_bounds, print_where_clause, href, print_abi_with_space, print_constness_with_space, print_default_space,
Buffer, PrintWithSpace, print_generic_bounds, print_where_clause, Buffer, PrintWithSpace,
}; };
use crate::html::markdown::{Markdown, MarkdownHtml, MarkdownSummaryLine}; use crate::html::markdown::{Markdown, MarkdownHtml, MarkdownSummaryLine};
@ -826,21 +826,45 @@ fn assoc_type(
fn render_stability_since_raw( fn render_stability_since_raw(
w: &mut Buffer, w: &mut Buffer,
ver: Option<&str>, ver: Option<&str>,
const_ver: Option<&str>, const_stability: Option<&ConstStability>,
containing_ver: Option<&str>, containing_ver: Option<&str>,
containing_const_ver: Option<&str>, containing_const_ver: Option<&str>,
) { ) {
let ver = ver.filter(|inner| !inner.is_empty()); let ver = ver.filter(|inner| !inner.is_empty());
let const_ver = const_ver.filter(|inner| !inner.is_empty());
match (ver, const_ver) { match (ver, const_stability) {
(Some(v), Some(cv)) if const_ver != containing_const_ver => { // stable and const stable
(Some(v), Some(ConstStability { level: StabilityLevel::Stable { since }, .. }))
if Some(since.as_str()).as_deref() != containing_const_ver =>
{
write!( write!(
w, w,
"<span class=\"since\" title=\"Stable since Rust version {0}, const since {1}\">{0} (const: {1})</span>", "<span class=\"since\" title=\"Stable since Rust version {0}, const since {1}\">{0} (const: {1})</span>",
v, cv v, since
); );
} }
// stable and const unstable
(
Some(v),
Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }),
) => {
write!(
w,
"<span class=\"since\" title=\"Stable since Rust version {0}, const unstable\">{0} (const: ",
v
);
if let Some(n) = issue {
write!(
w,
"<a href=\"https://github.com/rust-lang/rust/issues/{}\" title=\"Tracking issue for {}\">unstable</a>",
n, feature
);
} else {
write!(w, "unstable");
}
write!(w, ")</span>");
}
// stable
(Some(v), _) if ver != containing_ver => { (Some(v), _) if ver != containing_ver => {
write!( write!(
w, w,
@ -888,11 +912,13 @@ fn render_assoc_item(
} }
}; };
let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string(); let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string();
let constness = header.constness.print_with_space(); let constness =
print_constness_with_space(&header.constness, meth.const_stability(cx.tcx()));
let asyncness = header.asyncness.print_with_space(); let asyncness = header.asyncness.print_with_space();
let unsafety = header.unsafety.print_with_space(); let unsafety = header.unsafety.print_with_space();
let defaultness = print_default_space(meth.is_default()); let defaultness = print_default_space(meth.is_default());
let abi = print_abi_with_space(header.abi).to_string(); let abi = print_abi_with_space(header.abi).to_string();
// NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`. // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
let generics_len = format!("{:#}", g.print(cx)).len(); let generics_len = format!("{:#}", g.print(cx)).len();
let mut header_len = "fn ".len() let mut header_len = "fn ".len()
@ -917,15 +943,15 @@ fn render_assoc_item(
w.reserve(header_len + "<a href=\"\" class=\"fnname\">{".len() + "</a>".len()); w.reserve(header_len + "<a href=\"\" class=\"fnname\">{".len() + "</a>".len());
write!( write!(
w, w,
"{}{}{}{}{}{}{}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\ "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn <a href=\"{href}\" class=\"fnname\">{name}</a>\
{generics}{decl}{notable_traits}{where_clause}", {generics}{decl}{notable_traits}{where_clause}",
indent_str, indent = indent_str,
vis, vis = vis,
constness, constness = constness,
asyncness, asyncness = asyncness,
unsafety, unsafety = unsafety,
defaultness, defaultness = defaultness,
abi, abi = abi,
href = href, href = href,
name = name, name = name,
generics = g.print(cx), generics = g.print(cx),
@ -1583,7 +1609,7 @@ fn render_rightside(
render_stability_since_raw( render_stability_since_raw(
w, w,
item.stable_since(tcx).as_deref(), item.stable_since(tcx).as_deref(),
item.const_stable_since(tcx).as_deref(), item.const_stability(tcx),
containing_item.stable_since(tcx).as_deref(), containing_item.stable_since(tcx).as_deref(),
containing_item.const_stable_since(tcx).as_deref(), containing_item.const_stable_since(tcx).as_deref(),
); );

View file

@ -22,7 +22,9 @@ use crate::clean::{self, GetDefId};
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::formats::{AssocItemRender, Impl, RenderMode}; use crate::formats::{AssocItemRender, Impl, RenderMode};
use crate::html::escape::Escape; use crate::html::escape::Escape;
use crate::html::format::{print_abi_with_space, print_where_clause, Buffer, PrintWithSpace}; use crate::html::format::{
print_abi_with_space, print_constness_with_space, print_where_clause, Buffer, PrintWithSpace,
};
use crate::html::highlight; use crate::html::highlight;
use crate::html::layout::Page; use crate::html::layout::Page;
use crate::html::markdown::MarkdownSummaryLine; use crate::html::markdown::MarkdownSummaryLine;
@ -94,7 +96,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer,
render_stability_since_raw( render_stability_since_raw(
buf, buf,
item.stable_since(cx.tcx()).as_deref(), item.stable_since(cx.tcx()).as_deref(),
item.const_stable_since(cx.tcx()).as_deref(), item.const_stability(cx.tcx()),
None, None,
None, None,
); );
@ -430,29 +432,36 @@ fn extra_info_tags(item: &clean::Item, parent: &clean::Item, tcx: TyCtxt<'_>) ->
} }
fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) { fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean::Function) {
let header_len = format!( let vis = it.visibility.print_with_space(it.def_id, cx).to_string();
"{}{}{}{}{:#}fn {}{:#}", let constness = print_constness_with_space(&f.header.constness, it.const_stability(cx.tcx()));
it.visibility.print_with_space(it.def_id, cx), let asyncness = f.header.asyncness.print_with_space();
f.header.constness.print_with_space(), let unsafety = f.header.unsafety.print_with_space();
f.header.asyncness.print_with_space(), let abi = print_abi_with_space(f.header.abi).to_string();
f.header.unsafety.print_with_space(), let name = it.name.as_ref().unwrap();
print_abi_with_space(f.header.abi),
it.name.as_ref().unwrap(), let generics_len = format!("{:#}", f.generics.print(cx)).len();
f.generics.print(cx), let header_len = "fn ".len()
) + vis.len()
.len(); + constness.len()
+ asyncness.len()
+ unsafety.len()
+ abi.len()
+ name.as_str().len()
+ generics_len;
w.write_str("<pre class=\"rust fn\">"); w.write_str("<pre class=\"rust fn\">");
render_attributes_in_pre(w, it, ""); render_attributes_in_pre(w, it, "");
w.reserve(header_len);
write!( write!(
w, w,
"{vis}{constness}{asyncness}{unsafety}{abi}fn \ "{vis}{constness}{asyncness}{unsafety}{abi}fn \
{name}{generics}{decl}{notable_traits}{where_clause}</pre>", {name}{generics}{decl}{notable_traits}{where_clause}</pre>",
vis = it.visibility.print_with_space(it.def_id, cx), vis = vis,
constness = f.header.constness.print_with_space(), constness = constness,
asyncness = f.header.asyncness.print_with_space(), asyncness = asyncness,
unsafety = f.header.unsafety.print_with_space(), unsafety = unsafety,
abi = print_abi_with_space(f.header.abi), abi = abi,
name = it.name.as_ref().unwrap(), name = name,
generics = f.generics.print(cx), generics = f.generics.print(cx),
where_clause = print_where_clause(&f.generics, cx, 0, true), where_clause = print_where_clause(&f.generics, cx, 0, true),
decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx), decl = f.decl.full_print(header_len, 0, f.header.asyncness, cx),
@ -1291,7 +1300,7 @@ fn render_stability_since(
render_stability_since_raw( render_stability_since_raw(
w, w,
item.stable_since(tcx).as_deref(), item.stable_since(tcx).as_deref(),
item.const_stable_since(tcx).as_deref(), item.const_stability(tcx),
containing_item.stable_since(tcx).as_deref(), containing_item.stable_since(tcx).as_deref(),
containing_item.const_stable_since(tcx).as_deref(), containing_item.const_stable_since(tcx).as_deref(),
) )

View file

@ -1,5 +1,5 @@
Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A.
with Reserved Font Name < Fira >, with Reserved Font Name < Fira >,
This Font Software is licensed under the SIL Open Font License, Version 1.1. This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at: This license is copied below, and is also available with a FAQ at:
@ -19,7 +19,7 @@ with others.
The OFL allows the licensed fonts to be used, studied, modified and The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded, fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives, names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The however, cannot be released under any other type of license. The

View file

@ -7,12 +7,20 @@
#![feature(foo, foo2)] #![feature(foo, foo2)]
#![feature(staged_api)] #![feature(staged_api)]
// @has 'foo/fn.foo.html' '//pre' 'pub unsafe fn foo() -> u32' // @has 'foo/fn.foo.html' '//pre' 'pub fn foo() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")] #[rustc_const_unstable(feature="foo", issue = "none")]
pub const unsafe fn foo() -> u32 { 42 } pub const fn foo() -> u32 { 42 }
// @has 'foo/fn.foo_unsafe.html' '//pre' 'pub unsafe fn foo_unsafe() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")]
pub const unsafe fn foo_unsafe() -> u32 { 42 }
// @has 'foo/fn.foo2.html' '//pre' 'pub const fn foo2() -> u32' // @has 'foo/fn.foo2.html' '//pre' 'pub const fn foo2() -> u32'
// @!has - '//span[@class="since"]'
#[unstable(feature = "humans", issue = "none")] #[unstable(feature = "humans", issue = "none")]
pub const fn foo2() -> u32 { 42 } pub const fn foo2() -> u32 { 42 }
@ -22,7 +30,9 @@ pub const fn foo2() -> u32 { 42 }
#[rustc_const_stable(feature = "rust1", since = "1.0.0")] #[rustc_const_stable(feature = "rust1", since = "1.0.0")]
pub const fn bar2() -> u32 { 42 } pub const fn bar2() -> u32 { 42 }
// @has 'foo/fn.foo2_gated.html' '//pre' 'pub const unsafe fn foo2_gated() -> u32' // @has 'foo/fn.foo2_gated.html' '//pre' 'pub const unsafe fn foo2_gated() -> u32'
// @!has - '//span[@class="since"]'
#[unstable(feature = "foo2", issue = "none")] #[unstable(feature = "foo2", issue = "none")]
pub const unsafe fn foo2_gated() -> u32 { 42 } pub const unsafe fn foo2_gated() -> u32 { 42 }
@ -33,15 +43,23 @@ pub const unsafe fn foo2_gated() -> u32 { 42 }
pub const unsafe fn bar2_gated() -> u32 { 42 } pub const unsafe fn bar2_gated() -> u32 { 42 }
// @has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32' // @has 'foo/fn.bar_not_gated.html' '//pre' 'pub const unsafe fn bar_not_gated() -> u32'
// @!has - '//span[@class="since"]'
pub const unsafe fn bar_not_gated() -> u32 { 42 } pub const unsafe fn bar_not_gated() -> u32 { 42 }
pub struct Foo; pub struct Foo;
impl Foo { impl Foo {
// @has 'foo/struct.Foo.html' '//div[@id="method.gated"]/code' 'pub unsafe fn gated() -> u32' // @has 'foo/struct.Foo.html' '//div[@id="method.gated"]/code' 'pub fn gated() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")] #[rustc_const_unstable(feature="foo", issue = "none")]
pub const unsafe fn gated() -> u32 { 42 } pub const fn gated() -> u32 { 42 }
// @has 'foo/struct.Foo.html' '//div[@id="method.gated_unsafe"]/code' 'pub unsafe fn gated_unsafe() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: unstable)'
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature="foo", issue = "none")]
pub const unsafe fn gated_unsafe() -> u32 { 42 }
// @has 'foo/struct.Foo.html' '//div[@id="method.stable_impl"]/code' 'pub const fn stable_impl() -> u32' // @has 'foo/struct.Foo.html' '//div[@id="method.stable_impl"]/code' 'pub const fn stable_impl() -> u32'
// @has - '//span[@class="since"]' '1.0.0 (const: 1.2.0)' // @has - '//span[@class="since"]' '1.0.0 (const: 1.2.0)'

View file

@ -2,13 +2,22 @@
#![deny(or_patterns_back_compat)] #![deny(or_patterns_back_compat)]
#![allow(unused_macros)] #![allow(unused_macros)]
macro_rules! foo { ($x:pat_param | $y:pat) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
macro_rules! bar { ($($x:pat_param)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! foo { ($x:pat_param | $y:pat) => {} }
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
macro_rules! bar { ($($x:pat_param)+ | $($y:pat)+) => {} }
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
macro_rules! baz { ($x:pat_param | $y:pat_param) => {} } // should be ok macro_rules! baz { ($x:pat_param | $y:pat_param) => {} } // should be ok
macro_rules! qux { ($x:pat_param | $y:pat) => {} } // should be ok macro_rules! qux { ($x:pat_param | $y:pat) => {} } // should be ok
macro_rules! ogg { ($x:pat_param | $y:pat_param) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! ogg { ($x:pat_param | $y:pat_param) => {} }
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
macro_rules! match_any { macro_rules! match_any {
( $expr:expr , $( $( $pat:pat_param )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro ( $expr:expr , $( $( $pat:pat_param )|+ => $expr_arm:expr ),+ ) => {
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
match $expr { match $expr {
$( $(
$( $pat => $expr_arm, )+ $( $pat => $expr_arm, )+

View file

@ -2,13 +2,22 @@
#![deny(or_patterns_back_compat)] #![deny(or_patterns_back_compat)]
#![allow(unused_macros)] #![allow(unused_macros)]
macro_rules! foo { ($x:pat | $y:pat) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! foo { ($x:pat | $y:pat) => {} }
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} }
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
macro_rules! baz { ($x:pat_param | $y:pat_param) => {} } // should be ok macro_rules! baz { ($x:pat_param | $y:pat_param) => {} } // should be ok
macro_rules! qux { ($x:pat_param | $y:pat) => {} } // should be ok macro_rules! qux { ($x:pat_param | $y:pat) => {} } // should be ok
macro_rules! ogg { ($x:pat | $y:pat_param) => {} } //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro macro_rules! ogg { ($x:pat | $y:pat_param) => {} }
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
macro_rules! match_any { macro_rules! match_any {
( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { //~ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => {
//~^ ERROR the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
//~| WARN this was previously accepted
match $expr { match $expr {
$( $(
$( $pat => $expr_arm, )+ $( $pat => $expr_arm, )+

View file

@ -1,5 +1,5 @@
error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
--> $DIR/macro-or-patterns-back-compat.rs:5:21 --> $DIR/macro-or-patterns-back-compat.rs:6:21
| |
LL | macro_rules! foo { ($x:pat | $y:pat) => {} } LL | macro_rules! foo { ($x:pat | $y:pat) => {} }
| ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param` | ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
@ -9,24 +9,35 @@ note: the lint level is defined here
| |
LL | #![deny(or_patterns_back_compat)] LL | #![deny(or_patterns_back_compat)]
| ^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
= note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
--> $DIR/macro-or-patterns-back-compat.rs:6:23 --> $DIR/macro-or-patterns-back-compat.rs:9:23
| |
LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} } LL | macro_rules! bar { ($($x:pat)+ | $($y:pat)+) => {} }
| ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param` | ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
= note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
--> $DIR/macro-or-patterns-back-compat.rs:9:21 --> $DIR/macro-or-patterns-back-compat.rs:14:21
| |
LL | macro_rules! ogg { ($x:pat | $y:pat_param) => {} } LL | macro_rules! ogg { ($x:pat | $y:pat_param) => {} }
| ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param` | ^^^^^^ help: use pat_param to preserve semantics: `$x:pat_param`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
= note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro error: the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro
--> $DIR/macro-or-patterns-back-compat.rs:11:26 --> $DIR/macro-or-patterns-back-compat.rs:18:26
| |
LL | ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { LL | ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => {
| ^^^^^^^^ help: use pat_param to preserve semantics: `$pat:pat_param` | ^^^^^^^^ help: use pat_param to preserve semantics: `$pat:pat_param`
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in the 2021 edition!
= note: for more information, see issue #84869 <https://github.com/rust-lang/rust/issues/84869>
error: aborting due to 4 previous errors error: aborting due to 4 previous errors

View file

@ -0,0 +1,59 @@
// check-pass
//
// Regression test for issue #78632
#![crate_type = "lib"]
pub trait Corge<T> {
type Fred;
}
impl Corge<u8> for () {
type Fred = u32;
}
pub trait Waldo {
type Quax;
}
impl Waldo for u32 {
type Quax = u8;
}
pub trait Grault
where
(): Corge<Self::Thud>,
{
type Thud;
fn bar(_: <() as Corge<Self::Thud>>::Fred) {}
}
impl<T> Grault for T
where
T: Waldo,
(): Corge<T::Quax>,
<() as Corge<T::Quax>>::Fred: Waldo,
{
type Thud = u8;
}
pub trait Plugh<I> {
fn baz();
}
#[derive(Copy, Clone, Debug)]
pub struct Qiz<T> {
foo: T,
}
impl<T> Plugh<<() as Corge<T::Thud>>::Fred> for Qiz<T>
where
T: Grault,
(): Corge<T::Thud>,
{
fn baz() {}
}
pub fn test() {
<Qiz<u32> as Plugh<u32>>::baz();
}

View file

@ -0,0 +1,22 @@
#![feature(min_type_alias_impl_trait)]
#![feature(impl_trait_in_bindings)]
#![allow(incomplete_features)]
type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
//~^ ERROR: hidden type for `impl Trait` captures lifetime that does not appear in bounds
//~| ERROR: the type `&'<empty> str` does not fulfill the required lifetime
//~| ERROR: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
trait Output<'a> {}
impl<'a> Output<'a> for &'a str {}
fn cool_fn<'a>(arg: &'a str) -> OpaqueOutputImpl<'a> {
let out: OpaqueOutputImpl<'a> = arg;
arg
}
fn main() {
let s = String::from("wassup");
cool_fn(&s);
}

View file

@ -0,0 +1,48 @@
error[E0700]: hidden type for `impl Trait` captures lifetime that does not appear in bounds
--> $DIR/issue-85113.rs:5:29
|
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^^^^^^^^^^^^^^^^^^^
|
note: hidden type `&'<empty> str` captures lifetime smaller than the function body
--> $DIR/issue-85113.rs:5:29
|
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^^^^^^^^^^^^^^^^^^^
error[E0477]: the type `&'<empty> str` does not fulfill the required lifetime
--> $DIR/issue-85113.rs:5:29
|
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^^^^^^^^^^^^^^^^^^^
|
note: type must outlive the lifetime `'a` as defined on the item at 5:23
--> $DIR/issue-85113.rs:5:23
|
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements
--> $DIR/issue-85113.rs:5:29
|
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^^^^^^^^^^^^^^^^^^^
|
= note: first, the lifetime cannot outlive the empty lifetime...
note: ...but the lifetime must also be valid for the lifetime `'a` as defined on the item at 5:23...
--> $DIR/issue-85113.rs:5:23
|
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^
note: ...so that the types are compatible
--> $DIR/issue-85113.rs:5:29
|
LL | type OpaqueOutputImpl<'a> = impl Output<'a> + 'a;
| ^^^^^^^^^^^^^^^^^^^^
= note: expected `Output<'a>`
found `Output<'_>`
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0477, E0495, E0700.
For more information about an error, try `rustc --explain E0477`.

View file

@ -342,7 +342,7 @@ We have prioritization labels and a sync-blocker label, which are described belo
- [P-low][p-low]: Requires attention (fix/response/evaluation) by a team member but isn't urgent. - [P-low][p-low]: Requires attention (fix/response/evaluation) by a team member but isn't urgent.
- [P-medium][p-medium]: Should be addressed by a team member until the next sync. - [P-medium][p-medium]: Should be addressed by a team member until the next sync.
- [P-high][p-high]: Should be immediately addressed and will require an out-of-cycle sync or a backport. - [P-high][p-high]: Should be immediately addressed and will require an out-of-cycle sync or a backport.
- [L-sync-blocker][l-sync-blocker]: An issue that "blocks" a sync. - [L-sync-blocker][l-sync-blocker]: An issue that "blocks" a sync.
Or rather: before the sync this should be addressed, Or rather: before the sync this should be addressed,
e.g. by removing a lint again, so it doesn't hit beta/stable. e.g. by removing a lint again, so it doesn't hit beta/stable.

View file

@ -95,7 +95,7 @@ As with `cargo check`, this includes dependencies that are members of the worksp
If you want to run Clippy **only** on the given crate, use the `--no-deps` option like this: If you want to run Clippy **only** on the given crate, use the `--no-deps` option like this:
```terminal ```terminal
cargo clippy -p example -- --no-deps cargo clippy -p example -- --no-deps
``` ```
### As a rustc replacement (`clippy-driver`) ### As a rustc replacement (`clippy-driver`)

View file

@ -178,7 +178,7 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
(Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp), (Path(lq, lp), Path(rq, rp)) => both(lq, rq, |l, r| eq_qself(l, r)) && eq_path(lp, rp),
(MacCall(l), MacCall(r)) => eq_mac_call(l, r), (MacCall(l), MacCall(r)) => eq_mac_call(l, r),
(Struct(lse), Struct(rse)) => { (Struct(lse), Struct(rse)) => {
eq_maybe_qself(&lse.qself, &rse.qself) eq_maybe_qself(&lse.qself, &rse.qself)
&& eq_path(&lse.path, &rse.path) && eq_path(&lse.path, &rse.path)
&& eq_struct_rest(&lse.rest, &rse.rest) && eq_struct_rest(&lse.rest, &rse.rest)
&& unordered_over(&lse.fields, &rse.fields, |l, r| eq_field(l, r)) && unordered_over(&lse.fields, &rse.fields, |l, r| eq_field(l, r))

View file

@ -96,9 +96,9 @@ cargo dev ide_setup
## lintcheck ## lintcheck
`cargo lintcheck` will build and run clippy on a fixed set of crates and generate a log of the results. `cargo lintcheck` will build and run clippy on a fixed set of crates and generate a log of the results.
You can `git diff` the updated log against its previous version and You can `git diff` the updated log against its previous version and
see what impact your lint made on a small set of crates. see what impact your lint made on a small set of crates.
If you add a new lint, please audit the resulting warnings and make sure If you add a new lint, please audit the resulting warnings and make sure
there are no false positives and that the suggestions are valid. there are no false positives and that the suggestions are valid.
Refer to the tools [README] for more details. Refer to the tools [README] for more details.

View file

@ -73,5 +73,5 @@ You can run `./lintcheck/target/debug/lintcheck --fix` which will run Clippy wit
print a warning if Clippys suggestions fail to apply (if the resulting code does not build). print a warning if Clippys suggestions fail to apply (if the resulting code does not build).
This lets us spot bad suggestions or false positives automatically in some cases. This lets us spot bad suggestions or false positives automatically in some cases.
Please note that the target dir should be cleaned afterwards since clippy will modify Please note that the target dir should be cleaned afterwards since clippy will modify
the downloaded sources which can lead to unexpected results when running lintcheck again afterwards. the downloaded sources which can lead to unexpected results when running lintcheck again afterwards.

View file

@ -363,7 +363,7 @@
$scope.bySearch = function (lint, index, array) { $scope.bySearch = function (lint, index, array) {
let searchStr = $scope.search; let searchStr = $scope.search;
// It can be `null` I haven't missed this value // It can be `null` I haven't missed this value
if (searchStr == null || searchStr.length < 3) { if (searchStr == null || searchStr.length < 3) {
return true; return true;
} }
@ -375,7 +375,7 @@
} }
// Search the description // Search the description
// The use of `for`-loops instead of `foreach` enables us to return early // The use of `for`-loops instead of `foreach` enables us to return early
let terms = searchStr.split(" "); let terms = searchStr.split(" ");
for (index = 0; index < terms.length; index++) { for (index = 0; index < terms.length; index++) {
if (lint.id.indexOf(terms[index]) !== -1) { if (lint.id.indexOf(terms[index]) !== -1) {
@ -463,7 +463,7 @@
let children = themeMenu.children; let children = themeMenu.children;
for (let index = 0; index < children.length; index++) { for (let index = 0; index < children.length; index++) {
let child = children[index]; let child = children[index];
child.addEventListener("click", function(e) { child.addEventListener("click", function(e) {
setTheme(child.id, true); setTheme(child.id, true);
}); });
@ -476,7 +476,7 @@
let enableHighlight = false; let enableHighlight = false;
let enableNight = false; let enableNight = false;
let enableAyu = false; let enableAyu = false;
if (theme == "ayu") { if (theme == "ayu") {
enableAyu = true; enableAyu = true;
} else if (theme == "coal" || theme == "navy") { } else if (theme == "coal" || theme == "navy") {

View file

@ -176,7 +176,7 @@ https://rust-lang.github.io/rustfmt/?version=v1.4.33&search=#imports_granularity
### Changed ### Changed
- Original comment indentation for trailing comments within an `if` is now taken into account when determining the indentation level to use for the trailing comment in formatted code. This does not modify any existing code formatted with rustfmt; it simply gives the programmer discretion to specify whether the comment is associated to the `else` block, or if the trailing comment is just a member of the `if` block. ([#1575](https://github.com/rust-lang/rustfmt/issues/1575), [#4120](https://github.com/rust-lang/rustfmt/issues/4120), [#4506](https://github.com/rust-lang/rustfmt/issues/4506)) - Original comment indentation for trailing comments within an `if` is now taken into account when determining the indentation level to use for the trailing comment in formatted code. This does not modify any existing code formatted with rustfmt; it simply gives the programmer discretion to specify whether the comment is associated to the `else` block, or if the trailing comment is just a member of the `if` block. ([#1575](https://github.com/rust-lang/rustfmt/issues/1575), [#4120](https://github.com/rust-lang/rustfmt/issues/4120), [#4506](https://github.com/rust-lang/rustfmt/issues/4506))
In this example the `// else comment` refers to the `else`: In this example the `// else comment` refers to the `else`:
```rust ```rust
@ -213,7 +213,7 @@ if toks.eat_token(Token::Word("modify"))? && toks.eat_token(Token::Word("labels"
### Fixed ### Fixed
- Formatting of empty blocks with attributes which only contained comments is no longer butchered.([#4475](https://github.com/rust-lang/rustfmt/issues/4475), [#4467](https://github.com/rust-lang/rustfmt/issues/4467), [#4452](https://github.com/rust-lang/rustfmt/issues/4452#issuecomment-705886282), [#4522](https://github.com/rust-lang/rustfmt/issues/4522)) - Formatting of empty blocks with attributes which only contained comments is no longer butchered.([#4475](https://github.com/rust-lang/rustfmt/issues/4475), [#4467](https://github.com/rust-lang/rustfmt/issues/4467), [#4452](https://github.com/rust-lang/rustfmt/issues/4452#issuecomment-705886282), [#4522](https://github.com/rust-lang/rustfmt/issues/4522))
- Indentation of trailing comments in non-empty extern blocks is now correct. ([#4120](https://github.com/rust-lang/rustfmt/issues/4120#issuecomment-696491872)) - Indentation of trailing comments in non-empty extern blocks is now correct. ([#4120](https://github.com/rust-lang/rustfmt/issues/4120#issuecomment-696491872))
### Install/Download Options ### Install/Download Options
- **crates.io package** - *pending* - **crates.io package** - *pending*
@ -297,7 +297,7 @@ if toks.eat_token(Token::Word("modify"))? && toks.eat_token(Token::Word("labels"
- Fix aligning comments of different group - Fix aligning comments of different group
- Fix flattening imports with a single `self`. - Fix flattening imports with a single `self`.
- Fix removing attributes on function parameters. - Fix removing attributes on function parameters.
- Fix removing `impl` keyword from opaque type. - Fix removing `impl` keyword from opaque type.
## [1.4.8] 2019-09-08 ## [1.4.8] 2019-09-08
@ -329,7 +329,7 @@ if toks.eat_token(Token::Word("modify"))? && toks.eat_token(Token::Word("labels"
- Add `--message-format` command line option to `cargo-fmt`. - Add `--message-format` command line option to `cargo-fmt`.
- Add `-l,--files-with-diff` command line option to `rustfmt`. - Add `-l,--files-with-diff` command line option to `rustfmt`.
- Add `json` emit mode. - Add `json` emit mode.
### Fixed ### Fixed
@ -380,7 +380,7 @@ if toks.eat_token(Token::Word("modify"))? && toks.eat_token(Token::Word("labels"
### Added ### Added
- Add new attribute `rustfmt::skip::attributes` to prevent rustfmt - Add new attribute `rustfmt::skip::attributes` to prevent rustfmt
from formatting an attribute #3665 from formatting an attribute #3665
### Changed ### Changed

View file

@ -17,7 +17,7 @@ To enable unstable options, set `unstable_features = true` in `rustfmt.toml` or
Below you find a detailed visual guide on all the supported configuration options of rustfmt: Below you find a detailed visual guide on all the supported configuration options of rustfmt:
## `array_width` ## `array_width`
Maximum width of an array literal before falling back to vertical formatting. Maximum width of an array literal before falling back to vertical formatting.
@ -25,11 +25,11 @@ Maximum width of an array literal before falling back to vertical formatting.
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) - **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes - **Stable**: Yes
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `array_width` will take precedence. By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `array_width` will take precedence.
See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
## `attr_fn_like_width` ## `attr_fn_like_width`
Maximum width of the args of a function-like attributes before falling back to vertical formatting. Maximum width of the args of a function-like attributes before falling back to vertical formatting.
@ -37,7 +37,7 @@ Maximum width of the args of a function-like attributes before falling back to v
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) - **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes - **Stable**: Yes
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `attr_fn_like_width` will take precedence. By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `attr_fn_like_width` will take precedence.
See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
@ -295,7 +295,7 @@ where
} }
``` ```
## `chain_width` ## `chain_width`
Maximum width of a chain to fit on one line. Maximum width of a chain to fit on one line.
@ -303,7 +303,7 @@ Maximum width of a chain to fit on one line.
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) - **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes - **Stable**: Yes
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `chain_width` will take precedence. By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `chain_width` will take precedence.
See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
@ -751,7 +751,7 @@ trait Lorem {
} }
``` ```
## `fn_call_width` ## `fn_call_width`
Maximum width of the args of a function call before falling back to vertical formatting. Maximum width of the args of a function call before falling back to vertical formatting.
@ -759,7 +759,7 @@ Maximum width of the args of a function call before falling back to vertical for
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) - **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes - **Stable**: Yes
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `fn_call_width` will take precedence. By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `fn_call_width` will take precedence.
See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
@ -2124,7 +2124,7 @@ Don't reformat out of line modules
- **Possible values**: `true`, `false` - **Possible values**: `true`, `false`
- **Stable**: No (tracking issue: #3389) - **Stable**: No (tracking issue: #3389)
## `single_line_if_else_max_width` ## `single_line_if_else_max_width`
Maximum line length for single line if-else expressions. A value of `0` (zero) results in if-else expressions always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`. Maximum line length for single line if-else expressions. A value of `0` (zero) results in if-else expressions always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`.
@ -2132,7 +2132,7 @@ Maximum line length for single line if-else expressions. A value of `0` (zero) r
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) - **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes - **Stable**: Yes
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `single_line_if_else_max_width` will take precedence. By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `single_line_if_else_max_width` will take precedence.
See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
@ -2313,7 +2313,7 @@ fn main() {
See also: [`indent_style`](#indent_style). See also: [`indent_style`](#indent_style).
## `struct_lit_width` ## `struct_lit_width`
Maximum width in the body of a struct literal before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`. Maximum width in the body of a struct literal before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`.
@ -2321,11 +2321,11 @@ Maximum width in the body of a struct literal before falling back to vertical fo
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) - **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes - **Stable**: Yes
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `struct_lit_width` will take precedence. By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `struct_lit_width` will take precedence.
See also [`max_width`](#max_width), [`use_small_heuristics`](#use_small_heuristics), and [`struct_lit_single_line`](#struct_lit_single_line) See also [`max_width`](#max_width), [`use_small_heuristics`](#use_small_heuristics), and [`struct_lit_single_line`](#struct_lit_single_line)
## `struct_variant_width` ## `struct_variant_width`
Maximum width in the body of a struct variant before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`. Maximum width in the body of a struct variant before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `use_small_heuristics` is set to `Off`.
@ -2333,7 +2333,7 @@ Maximum width in the body of a struct variant before falling back to vertical fo
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width) - **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
- **Stable**: Yes - **Stable**: Yes
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `struct_variant_width` will take precedence. By default this option is set as a percentage of [`max_width`](#max_width) provided by [`use_small_heuristics`](#use_small_heuristics), but a value set directly for `struct_variant_width` will take precedence.
See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics) See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
@ -2530,7 +2530,7 @@ fn main() {
This option can be used to simplify the management and bulk updates of the granular width configuration settings ([`fn_call_width`](#fn_call_width), [`attr_fn_like_width`](#attr_fn_like_width), [`struct_lit_width`](#struct_lit_width), [`struct_variant_width`](#struct_variant_width), [`array_width`](#array_width), [`chain_width`](#chain_width), [`single_line_if_else_max_width`](#single_line_if_else_max_width)), that respectively control when formatted constructs are multi-lined/vertical based on width. This option can be used to simplify the management and bulk updates of the granular width configuration settings ([`fn_call_width`](#fn_call_width), [`attr_fn_like_width`](#attr_fn_like_width), [`struct_lit_width`](#struct_lit_width), [`struct_variant_width`](#struct_variant_width), [`array_width`](#array_width), [`chain_width`](#chain_width), [`single_line_if_else_max_width`](#single_line_if_else_max_width)), that respectively control when formatted constructs are multi-lined/vertical based on width.
Note that explicitly provided values for the width configuration settings take precedence and override the calculated values determined by `use_small_heuristics`. Note that explicitly provided values for the width configuration settings take precedence and override the calculated values determined by `use_small_heuristics`.
- **Default value**: `"Default"` - **Default value**: `"Default"`
- **Possible values**: `"Default"`, `"Off"`, `"Max"` - **Possible values**: `"Default"`, `"Off"`, `"Max"`
@ -2595,7 +2595,7 @@ fn main() {
``` ```
#### `Off`: #### `Off`:
When `use_small_heuristics` is set to `Off`, the granular width settings are functionally disabled and ignored. See the documentation for the respective width config options for specifics. When `use_small_heuristics` is set to `Off`, the granular width settings are functionally disabled and ignored. See the documentation for the respective width config options for specifics.
```rust ```rust
enum Lorem { enum Lorem {

View file

@ -38,7 +38,7 @@ colourised diff will be printed so that the offending line(s) can quickly be
identified. identified.
Without explicit settings, the tests will be run using rustfmt's default Without explicit settings, the tests will be run using rustfmt's default
configuration. It is possible to run a test using non-default settings in several configuration. It is possible to run a test using non-default settings in several
ways. Firstly, you can include configuration parameters in comments at the top ways. Firstly, you can include configuration parameters in comments at the top
of the file. For example: to use 3 spaces per tab, start your test with of the file. For example: to use 3 spaces per tab, start your test with
`// rustfmt-tab_spaces: 3`. Just remember that the comment is part of the input, `// rustfmt-tab_spaces: 3`. Just remember that the comment is part of the input,

View file

@ -150,8 +150,8 @@ for its configuration.
Our visitor keeps track of the desired current indent due to blocks ( Our visitor keeps track of the desired current indent due to blocks (
`block_indent`). Each `visit_*` method reformats code according to this indent, `block_indent`). Each `visit_*` method reformats code according to this indent,
`config.comment_width()` and `config.max_width()`. Most reformatting that is done `config.comment_width()` and `config.max_width()`. Most reformatting that is done
in the `visit_*` methods is a bit hacky and is meant to be temporary until it can in the `visit_*` methods is a bit hacky and is meant to be temporary until it can
be done properly. be done properly.
There are a bunch of methods called `rewrite_*`. They do the bulk of the There are a bunch of methods called `rewrite_*`. They do the bulk of the

View file

@ -180,13 +180,13 @@ needs to be specified in `rustfmt.toml`, e.g., with `edition = "2018"`.
* For things you do not want rustfmt to mangle, use `#[rustfmt::skip]` * For things you do not want rustfmt to mangle, use `#[rustfmt::skip]`
* To prevent rustfmt from formatting a macro or an attribute, * To prevent rustfmt from formatting a macro or an attribute,
use `#[rustfmt::skip::macros(target_macro_name)]` or use `#[rustfmt::skip::macros(target_macro_name)]` or
`#[rustfmt::skip::attributes(target_attribute_name)]` `#[rustfmt::skip::attributes(target_attribute_name)]`
Example: Example:
```rust ```rust
#![rustfmt::skip::attributes(custom_attribute)] #![rustfmt::skip::attributes(custom_attribute)]
#[custom_attribute(formatting , here , should , be , Skipped)] #[custom_attribute(formatting , here , should , be , Skipped)]
#[rustfmt::skip::macros(html)] #[rustfmt::skip::macros(html)]

View file

@ -15,7 +15,7 @@ set -ex
# it again. # it again.
# #
#which cargo-fmt || cargo install --force #which cargo-fmt || cargo install --force
CFG_RELEASE=nightly CFG_RELEASE_CHANNEL=nightly cargo install --path . --force CFG_RELEASE=nightly CFG_RELEASE_CHANNEL=nightly cargo install --path . --force
echo "Integration tests for: ${INTEGRATION}" echo "Integration tests for: ${INTEGRATION}"
cargo fmt -- --version cargo fmt -- --version

View file

@ -85,7 +85,7 @@
outputHtml() { outputHtml() {
const ast = this.configurationDescriptions const ast = this.configurationDescriptions
.filter(({ head, text, stable }) => { .filter(({ head, text, stable }) => {
if ( if (
text.includes(this.searchCondition) === false && text.includes(this.searchCondition) === false &&
head.includes(this.searchCondition) === false head.includes(this.searchCondition) === false
@ -105,7 +105,7 @@
}, },
created: async function() { created: async function() {
const res = await axios.get(ConfigurationMdUrl); const res = await axios.get(ConfigurationMdUrl);
const { const {
about, about,
configurationAbout, configurationAbout,
configurationDescriptions configurationDescriptions
@ -144,7 +144,7 @@
const lastIndex = stack.length - 1; const lastIndex = stack.length - 1;
stack[lastIndex].push(next); stack[lastIndex].push(next);
return stack; return stack;
}, },
[[]]); [[]]);
}); });
} }
@ -179,7 +179,7 @@
configurationAbout, ...configurationDescriptions configurationAbout, ...configurationDescriptions
] = configurations; ] = configurations;
configurationAbout.value.links = {}; configurationAbout.value.links = {};
return { return {
about, about,
configurationAbout: configurationAbout.value, configurationAbout: configurationAbout.value,

View file

@ -318,7 +318,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
self.directory = directory; self.directory = directory;
} }
match (sub_mod.ast_mod_kind, sub_mod.items) { match (sub_mod.ast_mod_kind, sub_mod.items) {
(Some(Cow::Borrowed(ast::ModKind::Loaded(items, ast::Inline::No, _))), _) => { (Some(Cow::Borrowed(ast::ModKind::Loaded(items, _, _))), _) => {
self.visit_mod_from_ast(&items) self.visit_mod_from_ast(&items)
} }
(Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items), (Some(Cow::Owned(..)), Cow::Owned(items)) => self.visit_mod_outside_ast(items),

View file

@ -16,6 +16,7 @@ use crate::source_file;
use crate::{is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, Session}; use crate::{is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, Session};
mod configuration_snippet; mod configuration_snippet;
mod mod_resolver;
mod parser; mod parser;
const DIFF_CONTEXT_SIZE: usize = 3; const DIFF_CONTEXT_SIZE: usize = 3;

View file

@ -0,0 +1,25 @@
use std::io;
use std::path::PathBuf;
use super::read_config;
use crate::{FileName, Input, Session};
#[test]
fn nested_out_of_line_mods_loaded() {
// See also https://github.com/rust-lang/rustfmt/issues/4874
let filename = "tests/mod-resolver/issue-4874/main.rs";
let input_file = PathBuf::from(filename);
let config = read_config(&input_file);
let mut session = Session::<io::Stdout>::new(config, None);
let report = session
.format(Input::File(filename.into()))
.expect("Should not have had any execution errors");
let errors_by_file = &report.internal.borrow().0;
assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from(
"tests/mod-resolver/issue-4874/bar/baz.rs",
))));
assert!(errors_by_file.contains_key(&FileName::Real(PathBuf::from(
"tests/mod-resolver/issue-4874/foo/qux.rs",
))));
}

View file

@ -0,0 +1,5 @@
fn
fail_fmt_check
(
) {}

View file

@ -0,0 +1 @@
mod qux;

View file

@ -0,0 +1,5 @@
fn
badly_formatted
(
) {}

View file

@ -0,0 +1,8 @@
fn main() {
println!("Hello, world!");
}
mod foo;
mod bar {
mod baz;
}