about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock8
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs65
-rw-r--r--compiler/rustc_error_messages/locales/en-US/passes.ftl3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs23
-rw-r--r--compiler/rustc_passes/src/errors.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs142
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs22
-rw-r--r--library/std/src/sys/unix/thread_parker/darwin.rs131
-rw-r--r--library/std/src/sys/unix/thread_parker/mod.rs13
-rw-r--r--library/std/src/thread/tests.rs22
-rw-r--r--src/test/rustdoc-ui/doc_cfg_hide.rs11
-rw-r--r--src/test/rustdoc-ui/doc_cfg_hide.stderr40
-rw-r--r--src/test/ui/drop/drop_order.rs64
-rw-r--r--src/test/ui/lifetimes/unusual-rib-combinations.rs28
-rw-r--r--src/test/ui/lifetimes/unusual-rib-combinations.stderr61
-rw-r--r--src/test/ui/traits/issue-102989.rs16
-rw-r--r--src/test/ui/traits/issue-102989.stderr59
m---------src/tools/cargo0
18 files changed, 609 insertions, 103 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 0cc7f8a1c7c..f393a918094 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -297,7 +297,7 @@ dependencies = [
  "cargo-test-macro",
  "cargo-test-support",
  "cargo-util",
- "clap 4.0.9",
+ "clap 4.0.15",
  "crates-io",
  "curl",
  "curl-sys",
@@ -439,7 +439,7 @@ dependencies = [
 
 [[package]]
 name = "cargo-util"
-version = "0.2.1"
+version = "0.2.2"
 dependencies = [
  "anyhow",
  "core-foundation",
@@ -602,9 +602,9 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.0.9"
+version = "4.0.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "30607dd93c420c6f1f80b544be522a0238a7db35e6a12968d28910983fee0df0"
+checksum = "6bf8832993da70a4c6d13c581f4463c2bdda27b9bf1c5498dc4365543abe6d6f"
 dependencies = [
  "atty",
  "bitflags",
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index c55b4906302..ec9c3935020 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -387,32 +387,58 @@ impl<'hir> LoweringContext<'_, 'hir> {
         then: &Block,
         else_opt: Option<&Expr>,
     ) -> hir::ExprKind<'hir> {
-        let lowered_cond = self.lower_expr(cond);
-        let new_cond = self.manage_let_cond(lowered_cond);
+        let lowered_cond = self.lower_cond(cond);
         let then_expr = self.lower_block_expr(then);
         if let Some(rslt) = else_opt {
-            hir::ExprKind::If(new_cond, self.arena.alloc(then_expr), Some(self.lower_expr(rslt)))
+            hir::ExprKind::If(
+                lowered_cond,
+                self.arena.alloc(then_expr),
+                Some(self.lower_expr(rslt)),
+            )
         } else {
-            hir::ExprKind::If(new_cond, self.arena.alloc(then_expr), None)
+            hir::ExprKind::If(lowered_cond, self.arena.alloc(then_expr), None)
         }
     }
 
-    // If `cond` kind is `let`, returns `let`. Otherwise, wraps and returns `cond`
-    // in a temporary block.
-    fn manage_let_cond(&mut self, cond: &'hir hir::Expr<'hir>) -> &'hir hir::Expr<'hir> {
-        fn has_let_expr<'hir>(expr: &'hir hir::Expr<'hir>) -> bool {
-            match expr.kind {
-                hir::ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
-                hir::ExprKind::Let(..) => true,
+    // Lowers a condition (i.e. `cond` in `if cond` or `while cond`), wrapping it in a terminating scope
+    // so that temporaries created in the condition don't live beyond it.
+    fn lower_cond(&mut self, cond: &Expr) -> &'hir hir::Expr<'hir> {
+        fn has_let_expr(expr: &Expr) -> bool {
+            match &expr.kind {
+                ExprKind::Binary(_, lhs, rhs) => has_let_expr(lhs) || has_let_expr(rhs),
+                ExprKind::Let(..) => true,
                 _ => false,
             }
         }
-        if has_let_expr(cond) {
-            cond
-        } else {
-            let reason = DesugaringKind::CondTemporary;
-            let span_block = self.mark_span_with_reason(reason, cond.span, None);
-            self.expr_drop_temps(span_block, cond, AttrVec::new())
+
+        // We have to take special care for `let` exprs in the condition, e.g. in
+        // `if let pat = val` or `if foo && let pat = val`, as we _do_ want `val` to live beyond the
+        // condition in this case.
+        //
+        // In order to mantain the drop behavior for the non `let` parts of the condition,
+        // we still wrap them in terminating scopes, e.g. `if foo && let pat = val` essentially
+        // gets transformed into `if { let _t = foo; _t } && let pat = val`
+        match &cond.kind {
+            ExprKind::Binary(op @ Spanned { node: ast::BinOpKind::And, .. }, lhs, rhs)
+                if has_let_expr(cond) =>
+            {
+                let op = self.lower_binop(*op);
+                let lhs = self.lower_cond(lhs);
+                let rhs = self.lower_cond(rhs);
+
+                self.arena.alloc(self.expr(
+                    cond.span,
+                    hir::ExprKind::Binary(op, lhs, rhs),
+                    AttrVec::new(),
+                ))
+            }
+            ExprKind::Let(..) => self.lower_expr(cond),
+            _ => {
+                let cond = self.lower_expr(cond);
+                let reason = DesugaringKind::CondTemporary;
+                let span_block = self.mark_span_with_reason(reason, cond.span, None);
+                self.expr_drop_temps(span_block, cond, AttrVec::new())
+            }
         }
     }
 
@@ -439,14 +465,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
         body: &Block,
         opt_label: Option<Label>,
     ) -> hir::ExprKind<'hir> {
-        let lowered_cond = self.with_loop_condition_scope(|t| t.lower_expr(cond));
-        let new_cond = self.manage_let_cond(lowered_cond);
+        let lowered_cond = self.with_loop_condition_scope(|t| t.lower_cond(cond));
         let then = self.lower_block_expr(body);
         let expr_break = self.expr_break(span, AttrVec::new());
         let stmt_break = self.stmt_expr(span, expr_break);
         let else_blk = self.block_all(span, arena_vec![self; stmt_break], None);
         let else_expr = self.arena.alloc(self.expr_block(else_blk, AttrVec::new()));
-        let if_kind = hir::ExprKind::If(new_cond, self.arena.alloc(then), Some(else_expr));
+        let if_kind = hir::ExprKind::If(lowered_cond, self.arena.alloc(then), Some(else_expr));
         let if_expr = self.expr(span, if_kind, AttrVec::new());
         let block = self.block_expr(self.arena.alloc(if_expr));
         let span = self.lower_span(span.with_hi(cond.span.hi()));
diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl
index 1f1c9c29d66..4bc6bd9fb22 100644
--- a/compiler/rustc_error_messages/locales/en-US/passes.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl
@@ -145,6 +145,9 @@ passes_doc_test_takes_list =
 passes_doc_primitive =
     `doc(primitive)` should never have been stable
 
+passes_doc_cfg_hide_takes_list =
+    `#[doc(cfg_hide(...)]` takes a list of attributes
+
 passes_doc_test_unknown_any =
     unknown `doc` attribute `{$path}`
 
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index dab8ae47779..3c684fffac8 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -934,6 +934,22 @@ impl CheckAttrVisitor<'_> {
         is_valid
     }
 
+    /// Check that the `#![doc(cfg_hide(...))]` attribute only contains a list of attributes.
+    /// Returns `true` if valid.
+    fn check_doc_cfg_hide(&self, meta: &NestedMetaItem, hir_id: HirId) -> bool {
+        if meta.meta_item_list().is_some() {
+            true
+        } else {
+            self.tcx.emit_spanned_lint(
+                INVALID_DOC_ATTRIBUTES,
+                hir_id,
+                meta.span(),
+                errors::DocCfgHideTakesList,
+            );
+            false
+        }
+    }
+
     /// Runs various checks on `#[doc]` attributes. Returns `true` if valid.
     ///
     /// `specified_inline` should be initialized to `None` and kept for the scope
@@ -987,6 +1003,13 @@ impl CheckAttrVisitor<'_> {
                             is_valid = false;
                         }
 
+                        sym::cfg_hide
+                            if !self.check_attr_crate_level(attr, meta, hir_id)
+                                || !self.check_doc_cfg_hide(meta, hir_id) =>
+                        {
+                            is_valid = false;
+                        }
+
                         sym::inline | sym::no_inline
                             if !self.check_doc_inline(
                                 attr,
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 1cc81a9ab98..ed548341344 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -272,6 +272,10 @@ pub struct DocTestUnknown {
 pub struct DocTestTakesList;
 
 #[derive(LintDiagnostic)]
+#[diag(passes::doc_cfg_hide_takes_list)]
+pub struct DocCfgHideTakesList;
+
+#[derive(LintDiagnostic)]
 #[diag(passes::doc_primitive)]
 pub struct DocPrimitive;
 
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index cc877e2fd30..77ba7a82672 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -224,22 +224,14 @@ enum LifetimeUseSet {
 
 #[derive(Copy, Clone, Debug)]
 enum LifetimeRibKind {
-    /// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
-    Item,
-
+    // -- Ribs introducing named lifetimes
+    //
     /// This rib declares generic parameters.
+    /// Only for this kind the `LifetimeRib::bindings` field can be non-empty.
     Generics { binder: NodeId, span: Span, kind: LifetimeBinderKind },
 
-    /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
-    /// generics. We are disallowing this until we can decide on how we want to handle non-'static
-    /// lifetimes in const generics. See issue #74052 for discussion.
-    ConstGeneric,
-
-    /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
-    /// This function will emit an error if `generic_const_exprs` is not enabled, the body identified by
-    /// `body_id` is an anonymous constant and `lifetime_ref` is non-static.
-    AnonConst,
-
+    // -- Ribs introducing unnamed lifetimes
+    //
     /// Create a new anonymous lifetime parameter and reference it.
     ///
     /// If `report_in_path`, report an error when encountering lifetime elision in a path:
@@ -256,16 +248,31 @@ enum LifetimeRibKind {
     /// ```
     AnonymousCreateParameter { binder: NodeId, report_in_path: bool },
 
+    /// Replace all anonymous lifetimes by provided lifetime.
+    Elided(LifetimeRes),
+
+    // -- Barrier ribs that stop lifetime lookup, or continue it but produce an error later.
+    //
     /// Give a hard error when either `&` or `'_` is written. Used to
     /// rule out things like `where T: Foo<'_>`. Does not imply an
     /// error on default object bounds (e.g., `Box<dyn Foo>`).
     AnonymousReportError,
 
-    /// Replace all anonymous lifetimes by provided lifetime.
-    Elided(LifetimeRes),
-
     /// Signal we cannot find which should be the anonymous lifetime.
     ElisionFailure,
+
+    /// FIXME(const_generics): This patches over an ICE caused by non-'static lifetimes in const
+    /// generics. We are disallowing this until we can decide on how we want to handle non-'static
+    /// lifetimes in const generics. See issue #74052 for discussion.
+    ConstGeneric,
+
+    /// Non-static lifetimes are prohibited in anonymous constants under `min_const_generics`.
+    /// This function will emit an error if `generic_const_exprs` is not enabled, the body
+    /// identified by `body_id` is an anonymous constant and `lifetime_ref` is non-static.
+    AnonConst,
+
+    /// This rib acts as a barrier to forbid reference to lifetimes of a parent item.
+    Item,
 }
 
 #[derive(Copy, Clone, Debug)]
@@ -748,35 +755,31 @@ impl<'a: 'ast, 'ast> Visitor<'ast> for LateResolutionVisitor<'a, '_, 'ast> {
     fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
         match foreign_item.kind {
             ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => {
-                self.with_lifetime_rib(LifetimeRibKind::Item, |this| {
-                    this.with_generic_param_rib(
-                        &generics.params,
-                        ItemRibKind(HasGenericParams::Yes(generics.span)),
-                        LifetimeRibKind::Generics {
-                            binder: foreign_item.id,
-                            kind: LifetimeBinderKind::Item,
-                            span: generics.span,
-                        },
-                        |this| visit::walk_foreign_item(this, foreign_item),
-                    )
-                });
+                self.with_generic_param_rib(
+                    &generics.params,
+                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    LifetimeRibKind::Generics {
+                        binder: foreign_item.id,
+                        kind: LifetimeBinderKind::Item,
+                        span: generics.span,
+                    },
+                    |this| visit::walk_foreign_item(this, foreign_item),
+                );
             }
             ForeignItemKind::Fn(box Fn { ref generics, .. }) => {
-                self.with_lifetime_rib(LifetimeRibKind::Item, |this| {
-                    this.with_generic_param_rib(
-                        &generics.params,
-                        ItemRibKind(HasGenericParams::Yes(generics.span)),
-                        LifetimeRibKind::Generics {
-                            binder: foreign_item.id,
-                            kind: LifetimeBinderKind::Function,
-                            span: generics.span,
-                        },
-                        |this| visit::walk_foreign_item(this, foreign_item),
-                    )
-                });
+                self.with_generic_param_rib(
+                    &generics.params,
+                    ItemRibKind(HasGenericParams::Yes(generics.span)),
+                    LifetimeRibKind::Generics {
+                        binder: foreign_item.id,
+                        kind: LifetimeBinderKind::Function,
+                        span: generics.span,
+                    },
+                    |this| visit::walk_foreign_item(this, foreign_item),
+                );
             }
             ForeignItemKind::Static(..) => {
-                self.with_item_rib(|this| {
+                self.with_static_rib(|this| {
                     visit::walk_foreign_item(this, foreign_item);
                 });
             }
@@ -1391,9 +1394,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             return self.resolve_anonymous_lifetime(lifetime, false);
         }
 
-        let mut indices = (0..self.lifetime_ribs.len()).rev();
-        for i in &mut indices {
-            let rib = &self.lifetime_ribs[i];
+        let mut lifetime_rib_iter = self.lifetime_ribs.iter().rev();
+        while let Some(rib) = lifetime_rib_iter.next() {
             let normalized_ident = ident.normalize_to_macros_2_0();
             if let Some(&(_, res)) = rib.bindings.get(&normalized_ident) {
                 self.record_lifetime_res(lifetime.id, res, LifetimeElisionCandidate::Named);
@@ -1423,9 +1425,10 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                                     } else {
                                         LifetimeUseSet::Many
                                     }),
-                                    LifetimeRibKind::Generics { .. }
-                                    | LifetimeRibKind::ConstGeneric
-                                    | LifetimeRibKind::AnonConst => None,
+                                    LifetimeRibKind::Generics { .. } => None,
+                                    LifetimeRibKind::ConstGeneric | LifetimeRibKind::AnonConst => {
+                                        span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)
+                                    }
                                 })
                                 .unwrap_or(LifetimeUseSet::Many);
                             debug!(?use_ctxt, ?use_set);
@@ -1460,13 +1463,16 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     );
                     return;
                 }
-                _ => {}
+                LifetimeRibKind::AnonymousCreateParameter { .. }
+                | LifetimeRibKind::Elided(_)
+                | LifetimeRibKind::Generics { .. }
+                | LifetimeRibKind::ElisionFailure
+                | LifetimeRibKind::AnonymousReportError => {}
             }
         }
 
         let mut outer_res = None;
-        for i in indices {
-            let rib = &self.lifetime_ribs[i];
+        for rib in lifetime_rib_iter {
             let normalized_ident = ident.normalize_to_macros_2_0();
             if let Some((&outer, _)) = rib.bindings.get_key_value(&normalized_ident) {
                 outer_res = Some(outer);
@@ -1493,8 +1499,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             count: 1,
         };
         let elision_candidate = LifetimeElisionCandidate::Missing(missing_lifetime);
-        for i in (0..self.lifetime_ribs.len()).rev() {
-            let rib = &mut self.lifetime_ribs[i];
+        for rib in self.lifetime_ribs.iter().rev() {
             debug!(?rib.kind);
             match rib.kind {
                 LifetimeRibKind::AnonymousCreateParameter { binder, .. } => {
@@ -1534,9 +1539,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                     return;
                 }
                 LifetimeRibKind::Item => break,
-                LifetimeRibKind::Generics { .. }
-                | LifetimeRibKind::ConstGeneric
-                | LifetimeRibKind::AnonConst => {}
+                LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
+                LifetimeRibKind::AnonConst => {
+                    // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+                    span_bug!(lifetime.ident.span, "unexpected rib kind: {:?}", rib.kind)
+                }
             }
         }
         self.record_lifetime_res(lifetime.id, LifetimeRes::Error, elision_candidate);
@@ -1751,9 +1758,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                         self.report_missing_lifetime_specifiers(vec![missing_lifetime], None);
                         break;
                     }
-                    LifetimeRibKind::Generics { .. }
-                    | LifetimeRibKind::ConstGeneric
-                    | LifetimeRibKind::AnonConst => {}
+                    LifetimeRibKind::Generics { .. } | LifetimeRibKind::ConstGeneric => {}
+                    LifetimeRibKind::AnonConst => {
+                        // There is always an `Elided(LifetimeRes::Static)` inside an `AnonConst`.
+                        span_bug!(elided_lifetime_span, "unexpected rib kind: {:?}", rib.kind)
+                    }
                 }
             }
 
@@ -2204,7 +2213,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
             }
 
             ItemKind::Static(ref ty, _, ref expr) | ItemKind::Const(_, ref ty, ref expr) => {
-                self.with_item_rib(|this| {
+                self.with_static_rib(|this| {
                     this.with_lifetime_rib(LifetimeRibKind::Elided(LifetimeRes::Static), |this| {
                         this.visit_ty(ty);
                     });
@@ -2399,11 +2408,9 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         self.label_ribs.pop();
     }
 
-    fn with_item_rib(&mut self, f: impl FnOnce(&mut Self)) {
+    fn with_static_rib(&mut self, f: impl FnOnce(&mut Self)) {
         let kind = ItemRibKind(HasGenericParams::No);
-        self.with_lifetime_rib(LifetimeRibKind::Item, |this| {
-            this.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
-        })
+        self.with_rib(ValueNS, kind, |this| this.with_rib(TypeNS, kind, f))
     }
 
     // HACK(min_const_generics,const_evaluatable_unchecked): We
@@ -3938,7 +3945,7 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
         fn_id: NodeId,
         async_node_id: Option<(NodeId, Span)>,
     ) {
-        if let Some((async_node_id, _)) = async_node_id {
+        if let Some((async_node_id, span)) = async_node_id {
             let mut extra_lifetime_params =
                 self.r.extra_lifetime_params_map.get(&fn_id).cloned().unwrap_or_default();
             for rib in self.lifetime_ribs.iter().rev() {
@@ -3952,7 +3959,12 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
                             extra_lifetime_params.extend(earlier_fresh);
                         }
                     }
-                    _ => {}
+                    LifetimeRibKind::Generics { .. } => {}
+                    _ => {
+                        // We are in a function definition. We should only find `Generics`
+                        // and `AnonymousCreateParameter` inside the innermost `Item`.
+                        span_bug!(span, "unexpected rib kind: {:?}", rib.kind)
+                    }
                 }
             }
             self.r.extra_lifetime_params_map.insert(async_node_id, extra_lifetime_params);
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index fda6a2236b1..4431cf9f443 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -2937,19 +2937,15 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             ObligationCauseCode::BinOp { rhs_span: Some(span), is_lit, .. } if *is_lit => span,
             _ => return,
         };
-        match (
-            trait_ref.skip_binder().self_ty().kind(),
-            trait_ref.skip_binder().substs.type_at(1).kind(),
-        ) {
-            (ty::Float(_), ty::Infer(InferTy::IntVar(_))) => {
-                err.span_suggestion_verbose(
-                    rhs_span.shrink_to_hi(),
-                    "consider using a floating-point literal by writing it with `.0`",
-                    ".0",
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            _ => {}
+        if let ty::Float(_) = trait_ref.skip_binder().self_ty().kind()
+            && let ty::Infer(InferTy::IntVar(_)) = trait_ref.skip_binder().substs.type_at(1).kind()
+        {
+            err.span_suggestion_verbose(
+                rhs_span.shrink_to_hi(),
+                "consider using a floating-point literal by writing it with `.0`",
+                ".0",
+                Applicability::MaybeIncorrect,
+            );
         }
     }
 
diff --git a/library/std/src/sys/unix/thread_parker/darwin.rs b/library/std/src/sys/unix/thread_parker/darwin.rs
new file mode 100644
index 00000000000..2f5356fe227
--- /dev/null
+++ b/library/std/src/sys/unix/thread_parker/darwin.rs
@@ -0,0 +1,131 @@
+//! Thread parking for Darwin-based systems.
+//!
+//! Darwin actually has futex syscalls (`__ulock_wait`/`__ulock_wake`), but they
+//! cannot be used in `std` because they are non-public (their use will lead to
+//! rejection from the App Store) and because they are only available starting
+//! with macOS version 10.12, even though the minimum target version is 10.7.
+//!
+//! Therefore, we need to look for other synchronization primitives. Luckily, Darwin
+//! supports semaphores, which allow us to implement the behaviour we need with
+//! only one primitive (as opposed to a mutex-condvar pair). We use the semaphore
+//! provided by libdispatch, as the underlying Mach semaphore is only dubiously
+//! public.
+
+use crate::pin::Pin;
+use crate::sync::atomic::{
+    AtomicI8,
+    Ordering::{Acquire, Release},
+};
+use crate::time::Duration;
+
+type dispatch_semaphore_t = *mut crate::ffi::c_void;
+type dispatch_time_t = u64;
+
+const DISPATCH_TIME_NOW: dispatch_time_t = 0;
+const DISPATCH_TIME_FOREVER: dispatch_time_t = !0;
+
+// Contained in libSystem.dylib, which is linked by default.
+extern "C" {
+    fn dispatch_time(when: dispatch_time_t, delta: i64) -> dispatch_time_t;
+    fn dispatch_semaphore_create(val: isize) -> dispatch_semaphore_t;
+    fn dispatch_semaphore_wait(dsema: dispatch_semaphore_t, timeout: dispatch_time_t) -> isize;
+    fn dispatch_semaphore_signal(dsema: dispatch_semaphore_t) -> isize;
+    fn dispatch_release(object: *mut crate::ffi::c_void);
+}
+
+const EMPTY: i8 = 0;
+const NOTIFIED: i8 = 1;
+const PARKED: i8 = -1;
+
+pub struct Parker {
+    semaphore: dispatch_semaphore_t,
+    state: AtomicI8,
+}
+
+unsafe impl Sync for Parker {}
+unsafe impl Send for Parker {}
+
+impl Parker {
+    pub unsafe fn new(parker: *mut Parker) {
+        let semaphore = dispatch_semaphore_create(0);
+        assert!(
+            !semaphore.is_null(),
+            "failed to create dispatch semaphore for thread synchronization"
+        );
+        parker.write(Parker { semaphore, state: AtomicI8::new(EMPTY) })
+    }
+
+    // Does not need `Pin`, but other implementation do.
+    pub unsafe fn park(self: Pin<&Self>) {
+        // The semaphore counter must be zero at this point, because unparking
+        // threads will not actually increase it until we signalled that we
+        // are waiting.
+
+        // Change NOTIFIED to EMPTY and EMPTY to PARKED.
+        if self.state.fetch_sub(1, Acquire) == NOTIFIED {
+            return;
+        }
+
+        // Another thread may increase the semaphore counter from this point on.
+        // If it is faster than us, we will decrement it again immediately below.
+        // If we are faster, we wait.
+
+        // Ensure that the semaphore counter has actually been decremented, even
+        // if the call timed out for some reason.
+        while dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER) != 0 {}
+
+        // At this point, the semaphore counter is zero again.
+
+        // We were definitely woken up, so we don't need to check the state.
+        // Still, we need to reset the state using a swap to observe the state
+        // change with acquire ordering.
+        self.state.swap(EMPTY, Acquire);
+    }
+
+    // Does not need `Pin`, but other implementation do.
+    pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) {
+        if self.state.fetch_sub(1, Acquire) == NOTIFIED {
+            return;
+        }
+
+        let nanos = dur.as_nanos().try_into().unwrap_or(i64::MAX);
+        let timeout = dispatch_time(DISPATCH_TIME_NOW, nanos);
+
+        let timeout = dispatch_semaphore_wait(self.semaphore, timeout) != 0;
+
+        let state = self.state.swap(EMPTY, Acquire);
+        if state == NOTIFIED && timeout {
+            // If the state was NOTIFIED but semaphore_wait returned without
+            // decrementing the count because of a timeout, it means another
+            // thread is about to call semaphore_signal. We must wait for that
+            // to happen to ensure the semaphore count is reset.
+            while dispatch_semaphore_wait(self.semaphore, DISPATCH_TIME_FOREVER) != 0 {}
+        } else {
+            // Either a timeout occurred and we reset the state before any thread
+            // tried to wake us up, or we were woken up and reset the state,
+            // making sure to observe the state change with acquire ordering.
+            // Either way, the semaphore counter is now zero again.
+        }
+    }
+
+    // Does not need `Pin`, but other implementation do.
+    pub fn unpark(self: Pin<&Self>) {
+        let state = self.state.swap(NOTIFIED, Release);
+        if state == PARKED {
+            unsafe {
+                dispatch_semaphore_signal(self.semaphore);
+            }
+        }
+    }
+}
+
+impl Drop for Parker {
+    fn drop(&mut self) {
+        // SAFETY:
+        // We always ensure that the semaphore count is reset, so this will
+        // never cause an exception.
+        unsafe {
+            dispatch_release(self.semaphore);
+        }
+    }
+}
diff --git a/library/std/src/sys/unix/thread_parker/mod.rs b/library/std/src/sys/unix/thread_parker/mod.rs
index e2453580dc7..35f1e68a87e 100644
--- a/library/std/src/sys/unix/thread_parker/mod.rs
+++ b/library/std/src/sys/unix/thread_parker/mod.rs
@@ -11,7 +11,18 @@
 )))]
 
 cfg_if::cfg_if! {
-    if #[cfg(target_os = "netbsd")] {
+    if #[cfg(all(
+        any(
+            target_os = "macos",
+            target_os = "ios",
+            target_os = "watchos",
+            target_os = "tvos",
+        ),
+        not(miri),
+    ))] {
+        mod darwin;
+        pub use darwin::Parker;
+    } else if #[cfg(target_os = "netbsd")] {
         mod netbsd;
         pub use netbsd::Parker;
     } else {
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 130e47c8d44..dfb8765ab4e 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -245,6 +245,28 @@ fn test_try_panic_any_message_unit_struct() {
 }
 
 #[test]
+fn test_park_unpark_before() {
+    for _ in 0..10 {
+        thread::current().unpark();
+        thread::park();
+    }
+}
+
+#[test]
+fn test_park_unpark_called_other_thread() {
+    for _ in 0..10 {
+        let th = thread::current();
+
+        let _guard = thread::spawn(move || {
+            super::sleep(Duration::from_millis(50));
+            th.unpark();
+        });
+
+        thread::park();
+    }
+}
+
+#[test]
 fn test_park_timeout_unpark_before() {
     for _ in 0..10 {
         thread::current().unpark();
diff --git a/src/test/rustdoc-ui/doc_cfg_hide.rs b/src/test/rustdoc-ui/doc_cfg_hide.rs
new file mode 100644
index 00000000000..5d8791748a0
--- /dev/null
+++ b/src/test/rustdoc-ui/doc_cfg_hide.rs
@@ -0,0 +1,11 @@
+#![feature(doc_cfg_hide)]
+#![deny(warnings)]
+
+#![doc(cfg_hide = "test")] //~ ERROR
+//~^ WARN
+#![doc(cfg_hide)] //~ ERROR
+//~^ WARN
+
+#[doc(cfg_hide(doc))] //~ ERROR
+//~^ WARN
+pub fn foo() {}
diff --git a/src/test/rustdoc-ui/doc_cfg_hide.stderr b/src/test/rustdoc-ui/doc_cfg_hide.stderr
new file mode 100644
index 00000000000..03623368cd0
--- /dev/null
+++ b/src/test/rustdoc-ui/doc_cfg_hide.stderr
@@ -0,0 +1,40 @@
+error: this attribute can only be applied at the crate level
+  --> $DIR/doc_cfg_hide.rs:9:7
+   |
+LL | #[doc(cfg_hide(doc))]
+   |       ^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+   = note: read <https://doc.rust-lang.org/nightly/rustdoc/the-doc-attribute.html#at-the-crate-level> for more information
+note: the lint level is defined here
+  --> $DIR/doc_cfg_hide.rs:2:9
+   |
+LL | #![deny(warnings)]
+   |         ^^^^^^^^
+   = note: `#[deny(invalid_doc_attributes)]` implied by `#[deny(warnings)]`
+help: to apply to the crate, use an inner attribute
+   |
+LL | #![doc(cfg_hide(doc))]
+   | ~~~~~~~~~~~~~~~~~~~~~~
+
+error: `#[doc(cfg_hide(...)]` takes a list of attributes
+  --> $DIR/doc_cfg_hide.rs:4:8
+   |
+LL | #![doc(cfg_hide = "test")]
+   |        ^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: `#[doc(cfg_hide(...)]` takes a list of attributes
+  --> $DIR/doc_cfg_hide.rs:6:8
+   |
+LL | #![doc(cfg_hide)]
+   |        ^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #82730 <https://github.com/rust-lang/rust/issues/82730>
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/drop/drop_order.rs b/src/test/ui/drop/drop_order.rs
index e42150dcc09..ba1ac53aa7c 100644
--- a/src/test/ui/drop/drop_order.rs
+++ b/src/test/ui/drop/drop_order.rs
@@ -1,4 +1,6 @@
 // run-pass
+// compile-flags: -Z validate-mir
+#![feature(let_chains)]
 
 use std::cell::RefCell;
 use std::convert::TryInto;
@@ -116,6 +118,58 @@ impl DropOrderCollector {
         }
     }
 
+    fn let_chain(&self) {
+        // take the "then" branch
+        if self.option_loud_drop(2).is_some() // 2
+            && self.option_loud_drop(1).is_some() // 1
+            && let Some(_d) = self.option_loud_drop(4) { // 4
+            self.print(3); // 3
+        }
+
+        // take the "else" branch
+        if self.option_loud_drop(6).is_some() // 2
+            && self.option_loud_drop(5).is_some() // 1
+            && let None = self.option_loud_drop(7) { // 3
+            unreachable!();
+        } else {
+            self.print(8); // 4
+        }
+
+        // let exprs interspersed
+        if self.option_loud_drop(9).is_some() // 1
+            && let Some(_d) = self.option_loud_drop(13) // 5
+            && self.option_loud_drop(10).is_some() // 2
+            && let Some(_e) = self.option_loud_drop(12) { // 4
+            self.print(11); // 3
+        }
+
+        // let exprs first
+        if let Some(_d) = self.option_loud_drop(18) // 5
+            && let Some(_e) = self.option_loud_drop(17) // 4
+            && self.option_loud_drop(14).is_some() // 1
+            && self.option_loud_drop(15).is_some() { // 2
+                self.print(16); // 3
+            }
+
+        // let exprs last
+        if self.option_loud_drop(20).is_some() // 2
+            && self.option_loud_drop(19).is_some() // 1
+            && let Some(_d) = self.option_loud_drop(23) // 5
+            && let Some(_e) = self.option_loud_drop(22) { // 4
+                self.print(21); // 3
+        }
+    }
+
+    fn while_(&self) {
+        let mut v = self.option_loud_drop(4);
+        while let Some(_d) = v
+            && self.option_loud_drop(1).is_some()
+            && self.option_loud_drop(2).is_some() {
+            self.print(3);
+            v = None;
+        }
+    }
+
     fn assert_sorted(self) {
         assert!(
             self.0
@@ -142,4 +196,14 @@ fn main() {
     let collector = DropOrderCollector::default();
     collector.match_();
     collector.assert_sorted();
+
+    println!("-- let chain --");
+    let collector = DropOrderCollector::default();
+    collector.let_chain();
+    collector.assert_sorted();
+
+    println!("-- while --");
+    let collector = DropOrderCollector::default();
+    collector.while_();
+    collector.assert_sorted();
 }
diff --git a/src/test/ui/lifetimes/unusual-rib-combinations.rs b/src/test/ui/lifetimes/unusual-rib-combinations.rs
new file mode 100644
index 00000000000..b4c86aab863
--- /dev/null
+++ b/src/test/ui/lifetimes/unusual-rib-combinations.rs
@@ -0,0 +1,28 @@
+#![feature(inline_const)]
+
+struct S<'a>(&'a u8);
+fn foo() {}
+
+// Paren generic args in AnonConst
+fn a() -> [u8; foo::()] {
+//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+//~| ERROR mismatched types
+    panic!()
+}
+
+// Paren generic args in ConstGeneric
+fn b<const C: u8()>() {}
+//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+
+// Paren generic args in AnonymousReportError
+fn c<T = u8()>() {}
+//~^ ERROR parenthesized type parameters may only be used with a `Fn` trait
+//~| ERROR defaults for type parameters are only allowed in
+//~| WARN this was previously accepted
+
+// Elided lifetime in path in ConstGeneric
+fn d<const C: S>() {}
+//~^ ERROR missing lifetime specifier
+//~| ERROR `S<'static>` is forbidden as the type of a const generic parameter
+
+fn main() {}
diff --git a/src/test/ui/lifetimes/unusual-rib-combinations.stderr b/src/test/ui/lifetimes/unusual-rib-combinations.stderr
new file mode 100644
index 00000000000..6d7b4250698
--- /dev/null
+++ b/src/test/ui/lifetimes/unusual-rib-combinations.stderr
@@ -0,0 +1,61 @@
+error[E0106]: missing lifetime specifier
+  --> $DIR/unusual-rib-combinations.rs:24:15
+   |
+LL | fn d<const C: S>() {}
+   |               ^ expected named lifetime parameter
+   |
+help: consider introducing a named lifetime parameter
+   |
+LL | fn d<'a, const C: S<'a>>() {}
+   |      +++           ++++
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/unusual-rib-combinations.rs:7:16
+   |
+LL | fn a() -> [u8; foo::()] {
+   |                ^^^^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/unusual-rib-combinations.rs:14:15
+   |
+LL | fn b<const C: u8()>() {}
+   |               ^^^^ only `Fn` traits may use parentheses
+
+error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
+  --> $DIR/unusual-rib-combinations.rs:18:10
+   |
+LL | fn c<T = u8()>() {}
+   |          ^^^^ only `Fn` traits may use parentheses
+
+error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
+  --> $DIR/unusual-rib-combinations.rs:18:6
+   |
+LL | fn c<T = u8()>() {}
+   |      ^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
+   = note: `#[deny(invalid_type_param_default)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/unusual-rib-combinations.rs:7:16
+   |
+LL | fn a() -> [u8; foo::()] {
+   |                ^^^^^^^ expected `usize`, found fn item
+   |
+   = note: expected type `usize`
+           found fn item `fn() {foo}`
+
+error: `S<'static>` is forbidden as the type of a const generic parameter
+  --> $DIR/unusual-rib-combinations.rs:24:15
+   |
+LL | fn d<const C: S>() {}
+   |               ^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: more complex types are supported with `#![feature(adt_const_params)]`
+
+error: aborting due to 7 previous errors
+
+Some errors have detailed explanations: E0106, E0214, E0308.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/src/test/ui/traits/issue-102989.rs b/src/test/ui/traits/issue-102989.rs
new file mode 100644
index 00000000000..62f95272fbf
--- /dev/null
+++ b/src/test/ui/traits/issue-102989.rs
@@ -0,0 +1,16 @@
+// normalize-stderr-test "loaded from .*libcore-.*.rlib" -> "loaded from SYSROOT/libcore-*.rlib"
+
+#![feature(lang_items)]
+#[lang="sized"]
+trait Sized { } //~ ERROR found duplicate lang item `sized`
+
+fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+    //~^ ERROR `self` parameter is only allowed in associated functions
+    //~| ERROR cannot find type `Struct` in this scope
+    //~| ERROR mismatched types
+    let x = x << 1;
+    //~^ ERROR the size for values of type `{integer}` cannot be known at compilation time
+    //~| ERROR cannot find value `x` in this scope
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/issue-102989.stderr b/src/test/ui/traits/issue-102989.stderr
new file mode 100644
index 00000000000..efe1a246774
--- /dev/null
+++ b/src/test/ui/traits/issue-102989.stderr
@@ -0,0 +1,59 @@
+error: `self` parameter is only allowed in associated functions
+  --> $DIR/issue-102989.rs:7:15
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |               ^^^^ not semantically valid as function parameter
+   |
+   = note: associated functions are those in `impl` or `trait` definitions
+
+error[E0412]: cannot find type `Struct` in this scope
+  --> $DIR/issue-102989.rs:7:22
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                      ^^^^^^ not found in this scope
+
+error[E0425]: cannot find value `x` in this scope
+  --> $DIR/issue-102989.rs:11:13
+   |
+LL |     let x = x << 1;
+   |             ^ help: a local variable with a similar name exists: `f`
+
+error[E0152]: found duplicate lang item `sized`
+  --> $DIR/issue-102989.rs:5:1
+   |
+LL | trait Sized { }
+   | ^^^^^^^^^^^
+   |
+   = note: the lang item is first defined in crate `core` (which `std` depends on)
+   = note: first definition in `core` loaded from SYSROOT/libcore-*.rlib
+   = note: second definition in the local crate (`issue_102989`)
+
+error[E0277]: the size for values of type `{integer}` cannot be known at compilation time
+  --> $DIR/issue-102989.rs:11:15
+   |
+LL |     let x = x << 1;
+   |               ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-102989.rs:7:42
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |    ----------                            ^^^^ expected `&u32`, found `()`
+   |    |
+   |    implicitly returns `()` as its body has no tail or `return` expression
+   |
+note: consider returning one of these bindings
+  --> $DIR/issue-102989.rs:7:30
+   |
+LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
+   |                              ^
+...
+LL |     let x = x << 1;
+   |         ^
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0152, E0277, E0308, E0412, E0425.
+For more information about an error, try `rustc --explain E0152`.
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject b8f30cb23c4e5f20854a4f683325782b7cff983
+Subproject b332991a57c9d055f1864de1eed93e2178d4944