about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-12-05 21:46:58 +0000
committerbors <bors@rust-lang.org>2022-12-05 21:46:58 +0000
commit8e440b03761f725d452120a992723c7e261822b2 (patch)
treee85aa0fe3bd1dee381a66567ae7dbe9eaad23a51
parente1d819583f0bf13b016b119c1c2c43e6d3979450 (diff)
parent612e89a1fba354f36f4ae74096e3a69d1abfcbc8 (diff)
downloadrust-8e440b03761f725d452120a992723c7e261822b2.tar.gz
rust-8e440b03761f725d452120a992723c7e261822b2.zip
Auto merge of #105328 - matthiaskrgr:rollup-qnfksmq, r=matthiaskrgr
Rollup of 8 pull requests

Successful merges:

 - #104912 (PartialEq: PERs are homogeneous)
 - #104952 (Streamline the user experience for `x.py setup`)
 - #104953 (Ensure required submodules at the same time as updating existing submodules)
 - #105180 (Use proper HirId for async track_caller attribute check)
 - #105222 (std update libc version and freebsd image build dependencies)
 - #105223 (suggest parenthesis around ExprWithBlock BinOp ExprWithBlock)
 - #105230 (Skip recording resolution for duplicated generic params.)
 - #105301 (update Miri)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock4
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs32
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs4
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs19
-rw-r--r--compiler/rustc_resolve/src/late.rs2
-rw-r--r--library/core/src/cmp.rs5
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--src/bootstrap/flags.rs9
-rw-r--r--src/bootstrap/lib.rs50
-rw-r--r--src/bootstrap/setup.rs91
-rwxr-xr-xsrc/ci/docker/scripts/freebsd-toolchain.sh2
-rw-r--r--src/test/ui/async-await/track-caller/issue-105134.rs11
-rw-r--r--src/test/ui/async-await/track-caller/panic-track-caller.rs14
-rw-r--r--src/test/ui/const-generics/defaults/self-referential.rs4
-rw-r--r--src/test/ui/const-generics/defaults/self-referential.stderr11
-rw-r--r--src/test/ui/duplicate/duplicate-type-parameter.stderr4
-rw-r--r--src/test/ui/parser/expr-as-stmt.fixed12
-rw-r--r--src/test/ui/parser/expr-as-stmt.rs12
-rw-r--r--src/test/ui/parser/expr-as-stmt.stderr43
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs23
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.rs17
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.stderr28
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs102
25 files changed, 359 insertions, 172 deletions
diff --git a/Cargo.lock b/Cargo.lock
index dae79e5bc26..970b1719aa1 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2085,9 +2085,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.135"
+version = "0.2.138"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "68783febc7782c6c5cb401fbda4de5a9898be1762314da0bb2c10ced61f18b0c"
+checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
 dependencies = [
  "rustc-std-workspace-core",
 ]
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 4260805f1dd..695ccec0b1c 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -147,6 +147,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                 ),
                 ExprKind::Async(capture_clause, closure_node_id, block) => self.make_async_expr(
                     *capture_clause,
+                    None,
                     *closure_node_id,
                     None,
                     e.span,
@@ -584,6 +585,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     pub(super) fn make_async_expr(
         &mut self,
         capture_clause: CaptureBy,
+        outer_hir_id: Option<hir::HirId>,
         closure_node_id: NodeId,
         ret_ty: Option<hir::FnRetTy<'hir>>,
         span: Span,
@@ -651,18 +653,20 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
             hir::ExprKind::Closure(c)
         };
-        let parent_has_track_caller = self
-            .attrs
-            .values()
-            .find(|attrs| attrs.into_iter().find(|attr| attr.has_name(sym::track_caller)).is_some())
-            .is_some();
-        let unstable_span =
-            self.mark_span_with_reason(DesugaringKind::Async, span, self.allow_gen_future.clone());
 
-        let hir_id = if parent_has_track_caller {
-            let generator_hir_id = self.lower_node_id(closure_node_id);
+        let track_caller = outer_hir_id
+            .and_then(|id| self.attrs.get(&id.local_id))
+            .map_or(false, |attrs| attrs.into_iter().any(|attr| attr.has_name(sym::track_caller)));
+
+        let hir_id = self.lower_node_id(closure_node_id);
+        if track_caller {
+            let unstable_span = self.mark_span_with_reason(
+                DesugaringKind::Async,
+                span,
+                self.allow_gen_future.clone(),
+            );
             self.lower_attrs(
-                generator_hir_id,
+                hir_id,
                 &[Attribute {
                     kind: AttrKind::Normal(ptr::P(NormalAttr {
                         item: AttrItem {
@@ -677,10 +681,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     span: unstable_span,
                 }],
             );
-            generator_hir_id
-        } else {
-            self.lower_node_id(closure_node_id)
-        };
+        }
 
         let generator = hir::Expr { hir_id, kind: generator_kind, span: self.lower_span(span) };
 
@@ -1019,6 +1020,9 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
                 let async_body = this.make_async_expr(
                     capture_clause,
+                    // FIXME(nbdd0121): This should also use a proper HIR id so `#[track_caller]`
+                    // can be applied on async closures as well.
+                    None,
                     inner_closure_id,
                     async_ret_ty,
                     body.span,
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index f6275433fc5..9eda48e9329 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -253,8 +253,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     // only cares about the input argument patterns in the function
                     // declaration (decl), not the return types.
                     let asyncness = header.asyncness;
-                    let body_id =
-                        this.lower_maybe_async_body(span, &decl, asyncness, body.as_deref());
+                    let body_id = this.lower_maybe_async_body(
+                        span,
+                        hir_id,
+                        &decl,
+                        asyncness,
+                        body.as_deref(),
+                    );
 
                     let mut itctx = ImplTraitContext::Universal;
                     let (generics, decl) = this.lower_generics(generics, id, &mut itctx, |this| {
@@ -701,6 +706,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
     fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {
         let hir_id = self.lower_node_id(i.id);
+        self.lower_attrs(hir_id, &i.attrs);
         let trait_item_def_id = hir_id.expect_owner();
 
         let (generics, kind, has_default) = match &i.kind {
@@ -724,7 +730,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
             AssocItemKind::Fn(box Fn { sig, generics, body: Some(body), .. }) => {
                 let asyncness = sig.header.asyncness;
                 let body_id =
-                    self.lower_maybe_async_body(i.span, &sig.decl, asyncness, Some(&body));
+                    self.lower_maybe_async_body(i.span, hir_id, &sig.decl, asyncness, Some(&body));
                 let (generics, sig) = self.lower_method_sig(
                     generics,
                     sig,
@@ -759,7 +765,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             AssocItemKind::MacCall(..) => panic!("macro item shouldn't exist at this point"),
         };
 
-        self.lower_attrs(hir_id, &i.attrs);
         let item = hir::TraitItem {
             owner_id: trait_item_def_id,
             ident: self.lower_ident(i.ident),
@@ -798,6 +803,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
         // Since `default impl` is not yet implemented, this is always true in impls.
         let has_value = true;
         let (defaultness, _) = self.lower_defaultness(i.kind.defaultness(), has_value);
+        let hir_id = self.lower_node_id(i.id);
+        self.lower_attrs(hir_id, &i.attrs);
 
         let (generics, kind) = match &i.kind {
             AssocItemKind::Const(_, ty, expr) => {
@@ -810,8 +817,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
             AssocItemKind::Fn(box Fn { sig, generics, body, .. }) => {
                 self.current_item = Some(i.span);
                 let asyncness = sig.header.asyncness;
-                let body_id =
-                    self.lower_maybe_async_body(i.span, &sig.decl, asyncness, body.as_deref());
+                let body_id = self.lower_maybe_async_body(
+                    i.span,
+                    hir_id,
+                    &sig.decl,
+                    asyncness,
+                    body.as_deref(),
+                );
                 let (generics, sig) = self.lower_method_sig(
                     generics,
                     sig,
@@ -844,8 +856,6 @@ impl<'hir> LoweringContext<'_, 'hir> {
             AssocItemKind::MacCall(..) => panic!("`TyMac` should have been expanded by now"),
         };
 
-        let hir_id = self.lower_node_id(i.id);
-        self.lower_attrs(hir_id, &i.attrs);
         let item = hir::ImplItem {
             owner_id: hir_id.expect_owner(),
             ident: self.lower_ident(i.ident),
@@ -978,6 +988,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_maybe_async_body(
         &mut self,
         span: Span,
+        fn_id: hir::HirId,
         decl: &FnDecl,
         asyncness: Async,
         body: Option<&Block>,
@@ -1128,6 +1139,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
 
             let async_expr = this.make_async_expr(
                 CaptureBy::Value,
+                Some(fn_id),
                 closure_id,
                 None,
                 body.span,
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 1daca464b47..4f92477b5d8 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -32,11 +32,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     }
 
     pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) {
+        // This suggestion is incorrect for
+        // fn foo() -> bool { match () { () => true } || match () { () => true } }
         err.span_suggestion_short(
             span.shrink_to_hi(),
             "consider using a semicolon here",
             ";",
-            Applicability::MachineApplicable,
+            Applicability::MaybeIncorrect,
         );
     }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index fe3cfde2e63..f6a6ed379a2 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -390,20 +390,11 @@ impl<'a> Parser<'a> {
             // want to keep their span info to improve diagnostics in these cases in a later stage.
             (true, Some(AssocOp::Multiply)) | // `{ 42 } *foo = bar;` or `{ 42 } * 3`
             (true, Some(AssocOp::Subtract)) | // `{ 42 } -5`
-            (true, Some(AssocOp::Add)) // `{ 42 } + 42
-            // If the next token is a keyword, then the tokens above *are* unambiguously incorrect:
-            // `if x { a } else { b } && if y { c } else { d }`
-            if !self.look_ahead(1, |t| t.is_used_keyword()) => {
-                // These cases are ambiguous and can't be identified in the parser alone.
-                let sp = self.sess.source_map().start_point(self.token.span);
-                self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
-                false
-            }
-            (true, Some(AssocOp::LAnd)) |
-            (true, Some(AssocOp::LOr)) |
-            (true, Some(AssocOp::BitOr)) => {
-                // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the
-                // above due to #74233.
+            (true, Some(AssocOp::Add)) | // `{ 42 } + 42` (unary plus)
+            (true, Some(AssocOp::LAnd)) | // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`
+            (true, Some(AssocOp::LOr)) | // `{ 42 } || 42` ("logical or" or closure)
+            (true, Some(AssocOp::BitOr)) // `{ 42 } | 42` or `{ 42 } |x| 42`
+            => {
                 // These cases are ambiguous and can't be identified in the parser alone.
                 //
                 // Bitwise AND is left out because guessing intent is hard. We can make
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 51a53f7b37c..fc9c9334aea 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -2360,8 +2360,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     if let GenericParamKind::Lifetime = param.kind {
                         // Record lifetime res, so lowering knows there is something fishy.
                         self.record_lifetime_param(param.id, LifetimeRes::Error);
-                        continue;
                     }
+                    continue;
                 }
                 Entry::Vacant(entry) => {
                     entry.insert(param.ident.span);
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 5db5cbfc3df..949896e5748 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -29,8 +29,7 @@ use crate::marker::StructuralPartialEq;
 
 use self::Ordering::*;
 
-/// Trait for equality comparisons which are [partial equivalence
-/// relations](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
+/// Trait for equality comparisons.
 ///
 /// `x.eq(y)` can also be written `x == y`, and `x.ne(y)` can be written `x != y`.
 /// We use the easier-to-read infix notation in the remainder of this documentation.
@@ -38,6 +37,8 @@ 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 [`trait@Eq`].
+/// Formally speaking, when `Rhs == Self`, this trait corresponds to a [partial equivalence
+/// relation](https://en.wikipedia.org/wiki/Partial_equivalence_relation).
 ///
 /// Implementations must ensure that `eq` and `ne` are consistent with each other:
 ///
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index c10bfde4ddf..a7aefc26b97 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -15,7 +15,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core" }
-libc = { version = "0.2.135", default-features = false, features = ['rustc-dep-of-std'] }
+libc = { version = "0.2.138", default-features = false, features = ['rustc-dep-of-std'] }
 compiler_builtins = { version = "0.1.82" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs
index 2001e29bd2e..37a8eb884ef 100644
--- a/src/bootstrap/flags.rs
+++ b/src/bootstrap/flags.rs
@@ -143,7 +143,7 @@ pub enum Subcommand {
         args: Vec<String>,
     },
     Setup {
-        profile: Profile,
+        profile: Option<Profile>,
     },
 }
 
@@ -628,14 +628,15 @@ Arguments:
                         |path| format!("{} is not a valid UTF8 string", path.to_string_lossy())
                     ));
 
-                    profile_string.parse().unwrap_or_else(|err| {
+                    let profile = profile_string.parse().unwrap_or_else(|err| {
                         eprintln!("error: {}", err);
                         eprintln!("help: the available profiles are:");
                         eprint!("{}", Profile::all_for_help("- "));
                         crate::detail_exit(1);
-                    })
+                    });
+                    Some(profile)
                 } else {
-                    t!(crate::setup::interactive_path())
+                    None
                 };
                 Subcommand::Setup { profile }
             }
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index d69bced0b28..3ed53452309 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -542,16 +542,6 @@ impl Build {
             metrics: metrics::BuildMetrics::init(),
         };
 
-        build.verbose("finding compilers");
-        cc_detect::find(&mut build);
-        // When running `setup`, the profile is about to change, so any requirements we have now may
-        // be different on the next invocation. Don't check for them until the next time x.py is
-        // run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing.
-        if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
-            build.verbose("running sanity check");
-            sanity::check(&mut build);
-        }
-
         // If local-rust is the same major.minor as the current version, then force a
         // local-rebuild
         let local_version_verbose =
@@ -567,16 +557,34 @@ impl Build {
             build.local_rebuild = true;
         }
 
-        // Make sure we update these before gathering metadata so we don't get an error about missing
-        // Cargo.toml files.
-        let rust_submodules =
-            ["src/tools/rust-installer", "src/tools/cargo", "library/backtrace", "library/stdarch"];
-        for s in rust_submodules {
-            build.update_submodule(Path::new(s));
-        }
+        build.verbose("finding compilers");
+        cc_detect::find(&mut build);
+        // When running `setup`, the profile is about to change, so any requirements we have now may
+        // be different on the next invocation. Don't check for them until the next time x.py is
+        // run. This is ok because `setup` never runs any build commands, so it won't fail if commands are missing.
+        //
+        // Similarly, for `setup` we don't actually need submodules or cargo metadata.
+        if !matches!(build.config.cmd, Subcommand::Setup { .. }) {
+            build.verbose("running sanity check");
+            sanity::check(&mut build);
+
+            // Make sure we update these before gathering metadata so we don't get an error about missing
+            // Cargo.toml files.
+            let rust_submodules = [
+                "src/tools/rust-installer",
+                "src/tools/cargo",
+                "library/backtrace",
+                "library/stdarch",
+            ];
+            for s in rust_submodules {
+                build.update_submodule(Path::new(s));
+            }
+            // Now, update all existing submodules.
+            build.update_existing_submodules();
 
-        build.verbose("learning about cargo");
-        metadata::build(&mut build);
+            build.verbose("learning about cargo");
+            metadata::build(&mut build);
+        }
 
         build
     }
@@ -668,7 +676,7 @@ impl Build {
 
     /// If any submodule has been initialized already, sync it unconditionally.
     /// This avoids contributors checking in a submodule change by accident.
-    pub fn maybe_update_submodules(&self) {
+    pub fn update_existing_submodules(&self) {
         // Avoid running git when there isn't a git checkout.
         if !self.config.submodules(&self.rust_info()) {
             return;
@@ -697,8 +705,6 @@ impl Build {
             job::setup(self);
         }
 
-        self.maybe_update_submodules();
-
         if let Subcommand::Format { check, paths } = &self.config.cmd {
             return format::format(&builder::Builder::new(&self), *check, &paths);
         }
diff --git a/src/bootstrap/setup.rs b/src/bootstrap/setup.rs
index 04480277fe0..c7f98a7d0d1 100644
--- a/src/bootstrap/setup.rs
+++ b/src/bootstrap/setup.rs
@@ -1,15 +1,13 @@
+use crate::Config;
 use crate::{t, VERSION};
-use crate::{Config, TargetSelection};
 use std::env::consts::EXE_SUFFIX;
 use std::fmt::Write as _;
 use std::fs::File;
+use std::io::Write;
 use std::path::{Path, PathBuf, MAIN_SEPARATOR};
 use std::process::Command;
 use std::str::FromStr;
-use std::{
-    env, fmt, fs,
-    io::{self, Write},
-};
+use std::{fmt, fs, io};
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
 pub enum Profile {
@@ -81,38 +79,10 @@ impl fmt::Display for Profile {
     }
 }
 
-pub fn setup(config: &Config, profile: Profile) {
-    let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml"));
-
-    if path.exists() {
-        eprintln!(
-            "error: you asked `x.py` to setup a new config file, but one already exists at `{}`",
-            path.display()
-        );
-        eprintln!("help: try adding `profile = \"{}\"` at the top of {}", profile, path.display());
-        eprintln!(
-            "note: this will use the configuration in {}",
-            profile.include_path(&config.src).display()
-        );
-        crate::detail_exit(1);
-    }
-
-    let settings = format!(
-        "# Includes one of the default files in src/bootstrap/defaults\n\
-    profile = \"{}\"\n\
-    changelog-seen = {}\n",
-        profile, VERSION
-    );
-    t!(fs::write(path, settings));
-
-    let include_path = profile.include_path(&config.src);
-    println!("`x.py` will now use the configuration at {}", include_path.display());
-
-    let build = TargetSelection::from_user(&env!("BUILD_TRIPLE"));
+pub fn setup(config: &Config, profile: Option<Profile>) {
+    let profile = profile.unwrap_or_else(|| t!(interactive_path()));
     let stage_path =
-        ["build", build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
-
-    println!();
+        ["build", config.build.rustc_target_arg(), "stage1"].join(&MAIN_SEPARATOR.to_string());
 
     if !rustup_installed() && profile != Profile::User {
         eprintln!("`rustup` is not installed; cannot link `stage1` toolchain");
@@ -134,8 +104,6 @@ pub fn setup(config: &Config, profile: Profile) {
         Profile::User => &["dist", "build"],
     };
 
-    println!();
-
     t!(install_git_hook_maybe(&config));
 
     println!();
@@ -150,6 +118,36 @@ pub fn setup(config: &Config, profile: Profile) {
             "For more suggestions, see https://rustc-dev-guide.rust-lang.org/building/suggested.html"
         );
     }
+
+    let path = &config.config.clone().unwrap_or(PathBuf::from("config.toml"));
+    setup_config_toml(path, profile, config);
+}
+
+fn setup_config_toml(path: &PathBuf, profile: Profile, config: &Config) {
+    if path.exists() {
+        eprintln!();
+        eprintln!(
+            "error: you asked `x.py` to setup a new config file, but one already exists at `{}`",
+            path.display()
+        );
+        eprintln!("help: try adding `profile = \"{}\"` at the top of {}", profile, path.display());
+        eprintln!(
+            "note: this will use the configuration in {}",
+            profile.include_path(&config.src).display()
+        );
+        crate::detail_exit(1);
+    }
+
+    let settings = format!(
+        "# Includes one of the default files in src/bootstrap/defaults\n\
+    profile = \"{}\"\n\
+    changelog-seen = {}\n",
+        profile, VERSION
+    );
+    t!(fs::write(path, settings));
+
+    let include_path = profile.include_path(&config.src);
+    println!("`x.py` will now use the configuration at {}", include_path.display());
 }
 
 fn rustup_installed() -> bool {
@@ -303,7 +301,18 @@ pub fn interactive_path() -> io::Result<Profile> {
 
 // install a git hook to automatically run tidy --bless, if they want
 fn install_git_hook_maybe(config: &Config) -> io::Result<()> {
+    let git = t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| {
+        assert!(output.status.success(), "failed to run `git`");
+        PathBuf::from(t!(String::from_utf8(output.stdout)).trim())
+    }));
+    let dst = git.join("hooks").join("pre-push");
+    if dst.exists() {
+        // The git hook has already been set up, or the user already has a custom hook.
+        return Ok(());
+    }
+
     let mut input = String::new();
+    println!();
     println!(
         "Rust's CI will automatically fail if it doesn't pass `tidy`, the internal tool for ensuring code quality.
 If you'd like, x.py can install a git hook for you that will automatically run `tidy --bless` before
@@ -329,12 +338,6 @@ undesirable, simply delete the `pre-push` file from .git/hooks."
 
     if should_install {
         let src = config.src.join("src").join("etc").join("pre-push.sh");
-        let git =
-            t!(config.git().args(&["rev-parse", "--git-common-dir"]).output().map(|output| {
-                assert!(output.status.success(), "failed to run `git`");
-                PathBuf::from(t!(String::from_utf8(output.stdout)).trim())
-            }));
-        let dst = git.join("hooks").join("pre-push");
         match fs::hard_link(src, &dst) {
             Err(e) => eprintln!(
                 "error: could not create hook {}: do you already have the git hook installed?\n{}",
diff --git a/src/ci/docker/scripts/freebsd-toolchain.sh b/src/ci/docker/scripts/freebsd-toolchain.sh
index 4a4cac1b723..17cd456b995 100755
--- a/src/ci/docker/scripts/freebsd-toolchain.sh
+++ b/src/ci/docker/scripts/freebsd-toolchain.sh
@@ -53,7 +53,7 @@ files_to_extract=(
 for lib in c cxxrt gcc_s m thr util; do
   files_to_extract=("${files_to_extract[@]}" "./lib/lib${lib}.*" "./usr/lib/lib${lib}.*")
 done
-for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm; do
+for lib in c++ c_nonshared compiler_rt execinfo gcc pthread rt ssp_nonshared procstat devstat kvm memstat; do
   files_to_extract=("${files_to_extract[@]}" "./usr/lib/lib${lib}.*")
 done
 
diff --git a/src/test/ui/async-await/track-caller/issue-105134.rs b/src/test/ui/async-await/track-caller/issue-105134.rs
new file mode 100644
index 00000000000..4e52b8e250b
--- /dev/null
+++ b/src/test/ui/async-await/track-caller/issue-105134.rs
@@ -0,0 +1,11 @@
+// check-pass
+// edition:2021
+
+#[track_caller]
+fn f() {
+    let _ = async {};
+}
+
+fn main() {
+    f();
+}
diff --git a/src/test/ui/async-await/track-caller/panic-track-caller.rs b/src/test/ui/async-await/track-caller/panic-track-caller.rs
index b113c56412f..5ebfeb3f36a 100644
--- a/src/test/ui/async-await/track-caller/panic-track-caller.rs
+++ b/src/test/ui/async-await/track-caller/panic-track-caller.rs
@@ -54,6 +54,19 @@ async fn foo_track_caller() {
     bar_track_caller().await
 }
 
+struct Foo;
+
+impl Foo {
+    #[track_caller]
+    async fn bar_assoc() {
+        panic!();
+    }
+}
+
+async fn foo_assoc() {
+    Foo::bar_assoc().await
+}
+
 fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
     let loc = Arc::new(Mutex::new(None));
 
@@ -73,4 +86,5 @@ fn panicked_at(f: impl FnOnce() + panic::UnwindSafe) -> u32 {
 fn main() {
     assert_eq!(panicked_at(|| block_on(foo())), 41);
     assert_eq!(panicked_at(|| block_on(foo_track_caller())), 54);
+    assert_eq!(panicked_at(|| block_on(foo_assoc())), 67);
 }
diff --git a/src/test/ui/const-generics/defaults/self-referential.rs b/src/test/ui/const-generics/defaults/self-referential.rs
new file mode 100644
index 00000000000..14a870dc39b
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/self-referential.rs
@@ -0,0 +1,4 @@
+trait Foo<const M: u8, const M: u8 = M> {}
+//~^ ERROR the name `M` is already used for a generic parameter in this item's generic parameters
+impl Foo<2> for () {}
+fn main() {}
diff --git a/src/test/ui/const-generics/defaults/self-referential.stderr b/src/test/ui/const-generics/defaults/self-referential.stderr
new file mode 100644
index 00000000000..170c1f7f7b2
--- /dev/null
+++ b/src/test/ui/const-generics/defaults/self-referential.stderr
@@ -0,0 +1,11 @@
+error[E0403]: the name `M` is already used for a generic parameter in this item's generic parameters
+  --> $DIR/self-referential.rs:1:30
+   |
+LL | trait Foo<const M: u8, const M: u8 = M> {}
+   |                 -            ^ already used
+   |                 |
+   |                 first use of `M`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0403`.
diff --git a/src/test/ui/duplicate/duplicate-type-parameter.stderr b/src/test/ui/duplicate/duplicate-type-parameter.stderr
index 6754574f0b9..628f898d5c8 100644
--- a/src/test/ui/duplicate/duplicate-type-parameter.stderr
+++ b/src/test/ui/duplicate/duplicate-type-parameter.stderr
@@ -55,10 +55,10 @@ LL | impl<T,T> Qux<T,T> for Option<T> {}
    |      first use of `T`
 
 error[E0207]: the type parameter `T` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/duplicate-type-parameter.rs:24:6
+  --> $DIR/duplicate-type-parameter.rs:24:8
    |
 LL | impl<T,T> Qux<T,T> for Option<T> {}
-   |      ^ unconstrained type parameter
+   |        ^ unconstrained type parameter
 
 error: aborting due to 8 previous errors
 
diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed
index 36709eea17c..b06f62794c4 100644
--- a/src/test/ui/parser/expr-as-stmt.fixed
+++ b/src/test/ui/parser/expr-as-stmt.fixed
@@ -64,4 +64,16 @@ fn asteroids() -> impl FnOnce() -> bool {
     { foo(); } || { true } //~ ERROR E0308
 }
 
+// https://github.com/rust-lang/rust/issues/105179
+fn r#match() -> i32 {
+    (match () { () => 1 }) + match () { () => 1 } //~ ERROR expected expression, found `+`
+    //~^ ERROR mismatched types
+}
+
+// https://github.com/rust-lang/rust/issues/102171
+fn r#unsafe() -> i32 {
+    (unsafe { 1 }) + unsafe { 1 } //~ ERROR expected expression, found `+`
+    //~^ ERROR mismatched types
+}
+
 fn main() {}
diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs
index 92bb972b240..b39d2b88647 100644
--- a/src/test/ui/parser/expr-as-stmt.rs
+++ b/src/test/ui/parser/expr-as-stmt.rs
@@ -64,4 +64,16 @@ fn asteroids() -> impl FnOnce() -> bool {
     { foo() } || { true } //~ ERROR E0308
 }
 
+// https://github.com/rust-lang/rust/issues/105179
+fn r#match() -> i32 {
+    match () { () => 1 } + match () { () => 1 } //~ ERROR expected expression, found `+`
+    //~^ ERROR mismatched types
+}
+
+// https://github.com/rust-lang/rust/issues/102171
+fn r#unsafe() -> i32 {
+    unsafe { 1 } + unsafe { 1 } //~ ERROR expected expression, found `+`
+    //~^ ERROR mismatched types
+}
+
 fn main() {}
diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr
index 6da4ac34067..18c8b0b7c50 100644
--- a/src/test/ui/parser/expr-as-stmt.stderr
+++ b/src/test/ui/parser/expr-as-stmt.stderr
@@ -55,6 +55,28 @@ help: parentheses are required to parse this as an expression
 LL |     ({ true }) | { true }
    |     +        +
 
+error: expected expression, found `+`
+  --> $DIR/expr-as-stmt.rs:69:26
+   |
+LL |     match () { () => 1 } + match () { () => 1 }
+   |                          ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     (match () { () => 1 }) + match () { () => 1 }
+   |     +                    +
+
+error: expected expression, found `+`
+  --> $DIR/expr-as-stmt.rs:75:18
+   |
+LL |     unsafe { 1 } + unsafe { 1 }
+   |                  ^ expected expression
+   |
+help: parentheses are required to parse this as an expression
+   |
+LL |     (unsafe { 1 }) + unsafe { 1 }
+   |     +            +
+
 error[E0308]: mismatched types
   --> $DIR/expr-as-stmt.rs:64:7
    |
@@ -201,7 +223,26 @@ help: parentheses are required to parse this as an expression
 LL |     ({ true }) || { true }
    |     +        +
 
-error: aborting due to 18 previous errors
+error[E0308]: mismatched types
+  --> $DIR/expr-as-stmt.rs:69:5
+   |
+LL |     match () { () => 1 } + match () { () => 1 }
+   |     ^^^^^^^^^^^^^^^^^^^^- help: consider using a semicolon here
+   |     |
+   |     expected `()`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/expr-as-stmt.rs:75:14
+   |
+LL |     unsafe { 1 } + unsafe { 1 }
+   |              ^ expected `()`, found integer
+   |
+help: you might have meant to return this value
+   |
+LL |     unsafe { return 1; } + unsafe { 1 }
+   |              ++++++  +
+
+error: aborting due to 22 previous errors
 
 Some errors have detailed explanations: E0308, E0600, E0614.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 0a6b9417cc2..8dd18ae98e6 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-cef44f53034eac46be3a0e3eec7b2b3d4ef5140b
+203c8765ea33c65d888febe0e8219c4bb11b0d89
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index 50c2ad75ca7..bcac873251f 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -45,7 +45,9 @@ pub struct Stacks {
 /// new pointer.
 #[derive(Copy, Clone, Hash, PartialEq, Eq)]
 enum RefKind {
-    /// `&mut` and `Box`.
+    /// `Box`.
+    Box,
+    /// `&mut`.
     Unique { two_phase: bool },
     /// `&` with or without interior mutability.
     Shared,
@@ -56,6 +58,7 @@ enum RefKind {
 impl fmt::Display for RefKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
+            RefKind::Box => write!(f, "Box"),
             RefKind::Unique { two_phase: false } => write!(f, "unique reference"),
             RefKind::Unique { two_phase: true } => write!(f, "unique reference (two-phase)"),
             RefKind::Shared => write!(f, "shared reference"),
@@ -654,15 +657,17 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
         let (perm, access) = match kind {
             RefKind::Unique { two_phase } => {
                 // Permission is Unique only if the type is `Unpin` and this is not twophase
-                let perm = if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) {
-                    Permission::Unique
+                if !two_phase && place.layout.ty.is_unpin(*this.tcx, this.param_env()) {
+                    (Permission::Unique, Some(AccessKind::Write))
                 } else {
-                    Permission::SharedReadWrite
-                };
-                // We do an access for all full borrows, even if `!Unpin`.
-                let access = if !two_phase { Some(AccessKind::Write) } else { None };
-                (perm, access)
+                    // FIXME: We emit `dereferenceable` for `!Unpin` mutable references, so we
+                    // should do fake accesses here. But then we run into
+                    // <https://github.com/rust-lang/unsafe-code-guidelines/issues/381>, so for now
+                    // we don't do that.
+                    (Permission::SharedReadWrite, None)
+                }
             }
+            RefKind::Box => (Permission::Unique, Some(AccessKind::Write)),
             RefKind::Raw { mutable: true } => {
                 // Creating a raw ptr does not count as an access
                 (Permission::SharedReadWrite, None)
@@ -853,7 +858,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 // Boxes get a weak protectors, since they may be deallocated.
                 self.retag_place(
                     place,
-                    RefKind::Unique { two_phase: false },
+                    RefKind::Box,
                     self.retag_cause,
                     /*protector*/
                     (self.kind == RetagKind::FnEntry).then_some(ProtectorKind::WeakProtector),
diff --git a/src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.rs b/src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.rs
deleted file mode 100644
index d660921bfe6..00000000000
--- a/src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//! Reborrowing a `&mut !Unpin` must still act like a (fake) read.
-use std::marker::PhantomPinned;
-
-struct NotUnpin(i32, PhantomPinned);
-
-fn main() {
-    unsafe {
-        let mut x = NotUnpin(0, PhantomPinned);
-        // Mutable borrow of `Unpin` field (with lifetime laundering)
-        let fieldref = &mut *(&mut x.0 as *mut i32);
-        // Mutable reborrow of the entire `x`, which is `!Unpin` but should
-        // still count as a read since we would add `dereferenceable`.
-        let _xref = &mut x;
-        // That read should have invalidated `fieldref`.
-        *fieldref = 0; //~ ERROR: /write access .* tag does not exist in the borrow stack/
-    }
-}
diff --git a/src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.stderr b/src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.stderr
deleted file mode 100644
index 3ef8a8e0e9c..00000000000
--- a/src/tools/miri/tests/fail/stacked_borrows/notunpin_dereferenceable_fakeread.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error: Undefined Behavior: attempting a write access using <TAG> at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
-  --> $DIR/notunpin_dereferenceable_fakeread.rs:LL:CC
-   |
-LL |         *fieldref = 0;
-   |         ^^^^^^^^^^^^^
-   |         |
-   |         attempting a write access using <TAG> at ALLOC[0x0], but that tag does not exist in the borrow stack for this location
-   |         this error occurs as part of an access at ALLOC[0x0..0x4]
-   |
-   = help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
-   = help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
-help: <TAG> was created by a Unique retag at offsets [0x0..0x4]
-  --> $DIR/notunpin_dereferenceable_fakeread.rs:LL:CC
-   |
-LL |         let fieldref = &mut *(&mut x.0 as *mut i32);
-   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-help: <TAG> was later invalidated at offsets [0x0..0x4] by a SharedReadWrite retag
-  --> $DIR/notunpin_dereferenceable_fakeread.rs:LL:CC
-   |
-LL |         let _xref = &mut x;
-   |                     ^^^^^^
-   = note: BACKTRACE:
-   = note: inside `main` at $DIR/notunpin_dereferenceable_fakeread.rs:LL:CC
-
-note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
-
-error: aborting due to previous error
-
diff --git a/src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs b/src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs
new file mode 100644
index 00000000000..3ba21552fd3
--- /dev/null
+++ b/src/tools/miri/tests/pass/stacked-borrows/future-self-referential.rs
@@ -0,0 +1,102 @@
+#![feature(pin_macro)]
+
+use std::future::*;
+use std::marker::PhantomPinned;
+use std::pin::*;
+use std::ptr;
+use std::task::*;
+
+struct Delay {
+    delay: usize,
+}
+
+impl Delay {
+    fn new(delay: usize) -> Self {
+        Delay { delay }
+    }
+}
+
+impl Future for Delay {
+    type Output = ();
+    fn poll(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<()> {
+        if self.delay > 0 {
+            self.delay -= 1;
+            Poll::Pending
+        } else {
+            Poll::Ready(())
+        }
+    }
+}
+
+async fn do_stuff() {
+    (&mut Delay::new(1)).await;
+}
+
+// Same thing implemented by hand
+struct DoStuff {
+    state: usize,
+    delay: Delay,
+    delay_ref: *mut Delay,
+    _marker: PhantomPinned,
+}
+
+impl DoStuff {
+    fn new() -> Self {
+        DoStuff {
+            state: 0,
+            delay: Delay::new(1),
+            delay_ref: ptr::null_mut(),
+            _marker: PhantomPinned,
+        }
+    }
+}
+
+impl Future for DoStuff {
+    type Output = ();
+    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
+        unsafe {
+            let this = self.get_unchecked_mut();
+            match this.state {
+                0 => {
+                    // Set up self-ref.
+                    this.delay_ref = &mut this.delay;
+                    // Move to next state.
+                    this.state = 1;
+                    Poll::Pending
+                }
+                1 => {
+                    let delay = &mut *this.delay_ref;
+                    Pin::new_unchecked(delay).poll(cx)
+                }
+                _ => unreachable!(),
+            }
+        }
+    }
+}
+
+fn run_fut<T>(fut: impl Future<Output = T>) -> T {
+    use std::sync::Arc;
+
+    struct MyWaker;
+    impl Wake for MyWaker {
+        fn wake(self: Arc<Self>) {
+            unimplemented!()
+        }
+    }
+
+    let waker = Waker::from(Arc::new(MyWaker));
+    let mut context = Context::from_waker(&waker);
+
+    let mut pinned = pin!(fut);
+    loop {
+        match pinned.as_mut().poll(&mut context) {
+            Poll::Pending => continue,
+            Poll::Ready(v) => return v,
+        }
+    }
+}
+
+fn main() {
+    run_fut(do_stuff());
+    run_fut(DoStuff::new());
+}