diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a07342ee96cdc..ff4fa1527e93a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -128,6 +128,9 @@ jobs: - name: ensure line endings are correct run: src/ci/scripts/verify-line-endings.sh if: success() && !env.SKIP_JOB + - name: ensure backported commits are in upstream branches + run: src/ci/scripts/verify-backported-commits.sh + if: success() && !env.SKIP_JOB - name: run the build run: src/ci/scripts/run-build-from-ci.sh env: @@ -499,6 +502,9 @@ jobs: - name: ensure line endings are correct run: src/ci/scripts/verify-line-endings.sh if: success() && !env.SKIP_JOB + - name: ensure backported commits are in upstream branches + run: src/ci/scripts/verify-backported-commits.sh + if: success() && !env.SKIP_JOB - name: run the build run: src/ci/scripts/run-build-from-ci.sh env: @@ -609,6 +615,9 @@ jobs: - name: ensure line endings are correct run: src/ci/scripts/verify-line-endings.sh if: success() && !env.SKIP_JOB + - name: ensure backported commits are in upstream branches + run: src/ci/scripts/verify-backported-commits.sh + if: success() && !env.SKIP_JOB - name: run the build run: src/ci/scripts/run-build-from-ci.sh env: diff --git a/.mailmap b/.mailmap index d1f5ca9371f62..2fbb480b85edf 100644 --- a/.mailmap +++ b/.mailmap @@ -101,6 +101,7 @@ Falco Hirschenberger Felix S. Klock II Felix S Klock II Flaper Fesp Florian Wilkens Florian Wilkens +Frank Steffahn Gareth Daniel Smith gareth Gareth Daniel Smith Gareth Smith Georges Dubus diff --git a/RELEASES.md b/RELEASES.md index 1d9ad3160f77e..2e7077ed2065e 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -70,6 +70,7 @@ Cargo - [The package definition in `cargo metadata` now includes the `"default_run"` field from the manifest.][cargo/9550] - [Added `cargo d` as an alias for `cargo doc`.][cargo/9680] +- [Added `{lib}` as formatting option for `cargo tree` to print the "lib_name" of packages.][cargo/9663] Rustdoc ------- @@ -146,18 +147,13 @@ Version 1.54.0 (2021-07-29) Language ----------------------- -- [You can now use macros for values in built-in attribute macros.][83366] - While a seemingly minor addition on its own, this enables a lot of - powerful functionality when combined correctly. Most notably you can - now include external documentation in your crate by writing the following. +- [You can now use macros for values in some built-in attributes.][83366] + This primarily allows you to call macros within the `#[doc]` attribute. For + example, to include external documentation in your crate, you can now write + the following: ```rust #![doc = include_str!("README.md")] ``` - You can also use this to include auto-generated modules: - ```rust - #[path = concat!(env!("OUT_DIR"), "/generated.rs")] - mod generated; - ``` - [You can now cast between unsized slice types (and types which contain unsized slices) in `const fn`.][85078] diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs index a28762ac485ec..74e50c606107f 100644 --- a/src/bootstrap/sanity.rs +++ b/src/bootstrap/sanity.rs @@ -166,11 +166,6 @@ pub fn check(build: &mut Build) { } for target in &build.targets { - // Can't compile for iOS unless we're on macOS - if target.contains("apple-ios") && !build.build.contains("apple-darwin") { - panic!("the iOS target is only supported on macOS"); - } - build .config .target_config diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index 59a1d06dabd21..6417f5a984ad5 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -206,6 +206,10 @@ x--expand-yaml-anchors--remove: run: src/ci/scripts/verify-line-endings.sh <<: *step + - name: ensure backported commits are in upstream branches + run: src/ci/scripts/verify-backported-commits.sh + <<: *step + - name: run the build run: src/ci/scripts/run-build-from-ci.sh env: diff --git a/src/ci/scripts/verify-backported-commits.sh b/src/ci/scripts/verify-backported-commits.sh new file mode 100755 index 0000000000000..1023e4b0e2837 --- /dev/null +++ b/src/ci/scripts/verify-backported-commits.sh @@ -0,0 +1,150 @@ +#!/bin/bash +# Ensure commits in beta are in master & commits in stable are in beta + master. +set -euo pipefail +IFS=$'\n\t' + +source "$(cd "$(dirname "$0")" && pwd)/../shared.sh" + +# We don't care about commits that predate this automation check, so we pass a +# `` argument to `git cherry`. +BETA_LIMIT="53fd98ca776cb875bc9e5514f56b52eb74f9e7a9" +STABLE_LIMIT="a178d0322ce20e33eac124758e837cbd80a6f633" + +verify_backported_commits_main() { + ci_base_branch=$(ciBaseBranch) + + if [[ "$ci_base_branch" != "beta" && "$ci_base_branch" != "stable" ]]; then + echo 'Skipping. This is only run when merging to the beta or stable branches.' + exit 0 + fi + + echo 'git: unshallowing the repository so we can check commits' + git fetch \ + --no-tags \ + --no-recurse-submodules \ + --progress \ + --prune \ + --unshallow + + if [[ $ci_base_branch == "beta" ]]; then + verify_cherries master "$BETA_LIMIT" \ + || exit 1 + + elif [[ $ci_base_branch == "stable" ]]; then + (verify_cherries master "$STABLE_LIMIT" \ + & verify_cherries beta "$STABLE_LIMIT") \ + || exit 1 + + fi +} + +# Verify all commits in `HEAD` are backports of a commit in . See +# https://git-scm.com/docs/git-cherry for an explanation of the arguments. +# +# $1 = +# $2 = +verify_cherries() { + # commits that lack a `backport-of` comment. + local no_backports=() + # commits with an incorrect `backport-of` comment. + local bad_backports=() + + commits=$(git cherry "origin/$1" HEAD "$2") + + if [[ -z "$commits" ]]; then + echo "All commits in \`HEAD\` are present in \`$1\`" + return 0 + fi + + commits=$(echo "$commits" | grep '^\+' | cut -c 3-) + + while read sha; do + # Check each commit in .. + backport_sha=$(get_backport "$sha") + + if [[ "$backport_sha" == "nothing" ]]; then + echo "✓ \`$sha\` backports nothing" + continue + fi + + if [[ -z "$backport_sha" ]]; then + no_backports+=("$sha") + continue + fi + + if ! is_in_master "$backport_sha"; then + bad_backports+=("$sha") + continue + fi + + echo "✓ \`$sha\` backports \`$backport_sha\`" + done <<< "$commits" + + failure=0 + + if [ ${#no_backports[@]} -ne 0 ]; then + echo 'Error: Could not find backports for all commits.' + echo + echo 'All commits in \`HEAD\` are required to have a corresponding upstream commit.' + echo 'It looks like the following commits:' + echo + for commit in "${no_backports[@]}"; do + echo " $commit" + done + echo + echo "do not match any commits in \`$1\`. If this was intended, add the text" + echo '\`backport-of: \`' + echo 'somewhere in the message of each of these commits.' + echo + failure=1 + fi + + if [ ${#bad_backports[@]} -ne 0 ]; then + echo 'Error: Found incorrectly marked commits.' + echo + echo 'The following commits:' + echo + for commit in "${bad_backports[@]}"; do + echo " $commit" + done + echo + echo 'have commit messages marked \`backport-of: \`, but the SHA is not in' + echo '\`master\`.' + echo + failure=1 + fi + + return $failure +} + +# Get the backport of a commit. It echoes one of: +# +# 1. A SHA of the backported commit +# 2. The string "nothing" +# 3. An empty string +# +# $1 = +get_backport() { + # This regex is: + # + # ^.* - throw away any extra starting characters + # backport-of: - prefix + # \s\? - optional space + # \(\) - capture group + # [a-f0-9]\+\|nothing - a SHA or the text 'nothing' + # .* - throw away any extra ending characters + # \1 - replace it with the first match + # {s//\1/p;q} - print the first occurrence and quit + # + git show -s --format=%B "$1" \ + | sed -n '/^.*backport-of:\s\?\([a-f0-9]\+\|nothing\).*/{s//\1/p;q}' +} + +# Check if a commit is in master. +# +# $1 = +is_in_master() { + git merge-base --is-ancestor "$1" origin/master 2> /dev/null +} + +verify_backported_commits_main diff --git a/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs b/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs new file mode 100644 index 0000000000000..8b51f55715e91 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/defining-use-submodule.rs @@ -0,0 +1,23 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// test that the type alias impl trait defining use is in a submodule + +fn main() {} + +type Foo = impl std::fmt::Display; +type Bar = impl std::fmt::Display; + +mod foo { + pub fn foo() -> super::Foo { + "foo" + } + + pub mod bar { + pub fn bar() -> crate::Bar { + 1 + } + } +} diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs index 766ee36c02be2..d87a25aad5830 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.rs @@ -3,8 +3,7 @@ fn main() {} trait Trait {} -type Underconstrained = impl 'static; -//~^ ERROR: at least one trait must be specified +type Underconstrained = impl Send; // no `Trait` bound fn underconstrain(_: T) -> Underconstrained { diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr index 99eb884a0e8f2..c73288329b013 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained.stderr @@ -1,11 +1,5 @@ -error: at least one trait must be specified - --> $DIR/generic_underconstrained.rs:6:35 - | -LL | type Underconstrained = impl 'static; - | ^^^^^^^^^^^^ - error[E0277]: the trait bound `T: Trait` is not satisfied - --> $DIR/generic_underconstrained.rs:10:31 + --> $DIR/generic_underconstrained.rs:9:31 | LL | fn underconstrain(_: T) -> Underconstrained { | ^^^^^^^^^^^^^^^^^^^ the trait `Trait` is not implemented for `T` @@ -13,13 +7,13 @@ LL | fn underconstrain(_: T) -> Underconstrained { note: required by a bound in `Underconstrained` --> $DIR/generic_underconstrained.rs:6:26 | -LL | type Underconstrained = impl 'static; +LL | type Underconstrained = impl Send; | ^^^^^ required by this bound in `Underconstrained` help: consider restricting type parameter `T` | LL | fn underconstrain(_: T) -> Underconstrained { | +++++++ -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs index cd7c962e2d15b..8adc0bf32a6aa 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.rs @@ -2,8 +2,7 @@ fn main() {} -type Underconstrained = impl 'static; -//~^ ERROR: at least one trait must be specified +type Underconstrained = impl Send; // not a defining use, because it doesn't define *all* possible generics fn underconstrained(_: U) -> Underconstrained { @@ -11,8 +10,7 @@ fn underconstrained(_: U) -> Underconstrained { 5u32 } -type Underconstrained2 = impl 'static; -//~^ ERROR: at least one trait must be specified +type Underconstrained2 = impl Send; // not a defining use, because it doesn't define *all* possible generics fn underconstrained2(_: U, _: V) -> Underconstrained2 { diff --git a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr index 1c1193705f99b..d77d978aa4449 100644 --- a/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_underconstrained2.stderr @@ -1,17 +1,5 @@ -error: at least one trait must be specified - --> $DIR/generic_underconstrained2.rs:5:45 - | -LL | type Underconstrained = impl 'static; - | ^^^^^^^^^^^^ - -error: at least one trait must be specified - --> $DIR/generic_underconstrained2.rs:14:46 - | -LL | type Underconstrained2 = impl 'static; - | ^^^^^^^^^^^^ - error[E0277]: `U` doesn't implement `Debug` - --> $DIR/generic_underconstrained2.rs:9:33 + --> $DIR/generic_underconstrained2.rs:8:33 | LL | fn underconstrained(_: U) -> Underconstrained { | ^^^^^^^^^^^^^^^^^^^ `U` cannot be formatted using `{:?}` because it doesn't implement `Debug` @@ -19,7 +7,7 @@ LL | fn underconstrained(_: U) -> Underconstrained { note: required by a bound in `Underconstrained` --> $DIR/generic_underconstrained2.rs:5:26 | -LL | type Underconstrained = impl 'static; +LL | type Underconstrained = impl Send; | ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained` help: consider restricting type parameter `U` | @@ -27,21 +15,21 @@ LL | fn underconstrained(_: U) -> Underconstrained { | +++++++++++++++++ error[E0277]: `V` doesn't implement `Debug` - --> $DIR/generic_underconstrained2.rs:18:43 + --> $DIR/generic_underconstrained2.rs:16:43 | LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | ^^^^^^^^^^^^^^^^^^^^ `V` cannot be formatted using `{:?}` because it doesn't implement `Debug` | note: required by a bound in `Underconstrained2` - --> $DIR/generic_underconstrained2.rs:14:27 + --> $DIR/generic_underconstrained2.rs:13:27 | -LL | type Underconstrained2 = impl 'static; +LL | type Underconstrained2 = impl Send; | ^^^^^^^^^^^^^^^ required by this bound in `Underconstrained2` help: consider restricting type parameter `V` | LL | fn underconstrained2(_: U, _: V) -> Underconstrained2 { | +++++++++++++++++ -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.rs b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs new file mode 100644 index 0000000000000..955d1288a457d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.rs @@ -0,0 +1,15 @@ +#![feature(type_alias_impl_trait)] + +type Foo = impl Sized; + +fn bar() -> Foo { + None + //~^ ERROR: type annotations needed [E0282] +} + +fn baz() -> Foo { + //~^ ERROR: concrete type differs from previous defining opaque type use + Some(()) +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr new file mode 100644 index 0000000000000..53cdf9e5b385f --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/incomplete-inference.stderr @@ -0,0 +1,21 @@ +error[E0282]: type annotations needed + --> $DIR/incomplete-inference.rs:6:5 + | +LL | None + | ^^^^ cannot infer type for type parameter `T` declared on the enum `Option` + +error: concrete type differs from previous defining opaque type use + --> $DIR/incomplete-inference.rs:10:1 + | +LL | fn baz() -> Foo { + | ^^^^^^^^^^^^^^^ expected `[type error]`, got `Option<()>` + | +note: previous use here + --> $DIR/incomplete-inference.rs:5:1 + | +LL | fn bar() -> Foo { + | ^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs new file mode 100644 index 0000000000000..f6a8302967060 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-dyn.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Foo = Box>; + +fn make_foo() -> Foo { + Box::new(vec![1, 2, 3].into_iter()) +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs new file mode 100644 index 0000000000000..fddecfcacf680 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-assoc-impl-trait.rs @@ -0,0 +1,19 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Foo = impl Iterator; + +fn make_foo() -> Foo { + vec![1, 2].into_iter() +} + +type Bar = impl Send; +type Baz = impl Iterator; + +fn make_baz() -> Baz { + vec!["1", "2"].into_iter() +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs new file mode 100644 index 0000000000000..299bdf562dc41 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.rs @@ -0,0 +1,13 @@ +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +// FIXME: this is ruled out for now but should work + +type Foo = fn() -> impl Send; +//~^ ERROR: `impl Trait` not allowed outside of function and method return types + +fn make_foo() -> Foo { + || 15 +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr new file mode 100644 index 0000000000000..1c5d57d4af761 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-fn-type.stderr @@ -0,0 +1,9 @@ +error[E0562]: `impl Trait` not allowed outside of function and method return types + --> $DIR/type-alias-impl-trait-fn-type.rs:6:20 + | +LL | type Foo = fn() -> impl Send; + | ^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0562`. diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs new file mode 100644 index 0000000000000..1a4064055db65 --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-struct.rs @@ -0,0 +1,12 @@ +// check-pass + +#![feature(type_alias_impl_trait)] +#![allow(dead_code)] + +type Foo = Vec; + +fn make_foo() -> Foo { + vec![true, false] +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs index 86c9d48214383..1f2d0e47ea3b2 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait-tuple.rs @@ -7,20 +7,19 @@ pub trait MyTrait {} impl MyTrait for bool {} +type Foo = impl MyTrait; + struct Blah { my_foo: Foo, - my_u8: u8 + my_u8: u8, } impl Blah { fn new() -> Blah { - Blah { - my_foo: make_foo(), - my_u8: 12 - } + Blah { my_foo: make_foo(), my_u8: 12 } } - fn into_inner(self) -> (Foo, u8) { - (self.my_foo, self.my_u8) + fn into_inner(self) -> (Foo, u8, Foo) { + (self.my_foo, self.my_u8, make_foo()) } } @@ -28,6 +27,4 @@ fn make_foo() -> Foo { true } -type Foo = impl MyTrait; - fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs index 80192d19af98b..d2c8c1f63df1c 100644 --- a/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs +++ b/src/test/ui/type-alias-impl-trait/type-alias-impl-trait.rs @@ -11,7 +11,6 @@ fn main() { assert_eq!(bar2().to_string(), "bar2"); let mut x = bar1(); x = bar2(); - assert_eq!(boo::boo().to_string(), "boo"); assert_eq!(my_iter(42u8).collect::>(), vec![42u8]); } @@ -33,15 +32,6 @@ fn bar2() -> Bar { "bar2" } -// definition in submodule -type Boo = impl std::fmt::Display; - -mod boo { - pub fn boo() -> super::Boo { - "boo" - } -} - type MyIter = impl Iterator; fn my_iter(t: T) -> MyIter { diff --git a/src/tools/cherry-pick.sh b/src/tools/cherry-pick.sh new file mode 100755 index 0000000000000..90539a96389b0 --- /dev/null +++ b/src/tools/cherry-pick.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -euo pipefail +IFS=$'\n\t' + +print_error() { + echo "Error: \`$1\` is not a valid commit. To debug, run:" + echo + echo " git rev-parse --verify $1" + echo +} + +full_sha() { + git rev-parse \ + --verify \ + --quiet \ + "$1^{object}" || print_error $1 +} + +commit_message_with_backport_note() { + message=$(git log --format=%B -n 1 $1) + echo $message | awk "NR==1{print; print \"\n(backport-of: $1)\"} NR!=1" +} + +cherry_pick_commit() { + sha=$(full_sha $1) + git cherry-pick $sha > /dev/null + git commit \ + --amend \ + --file <(commit_message_with_backport_note $sha) +} + +for arg ; do + cherry_pick_commit $arg +done