about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-10-08 21:13:27 +0000
committerbors <bors@rust-lang.org>2021-10-08 21:13:27 +0000
commitf8751436ffce35cd1b7291b03b394166b77ff0da (patch)
tree98ab538db2333c69214393e6b1ca36c74fac6f75
parent54bb4fec68cb592e23077896baea072919721573 (diff)
parentcda07c740cc98088dd383229dcc45e972c39b0fb (diff)
downloadrust-f8751436ffce35cd1b7291b03b394166b77ff0da.tar.gz
rust-f8751436ffce35cd1b7291b03b394166b77ff0da.zip
Auto merge of #89683 - GuillaumeGomez:rollup-q2mjd9m, r=GuillaumeGomez
Rollup of 6 pull requests

Successful merges:

 - #86506 (Don't normalize xform_ret_ty during method candidate assembly )
 - #89538 (Make rustdoc not highlight `->` and `=>` as operators)
 - #89649 (clippy::complexity fixes)
 - #89668 (Cfg hide more conditions for core and alloc)
 - #89669 (Remove special-casing of never primitive in rustdoc-json-types)
 - #89672 (Remove unwrap_or! macro)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_ast/src/lib.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs3
-rw-r--r--compiler/rustc_borrowck/src/dataflow.rs2
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs4
-rw-r--r--compiler/rustc_lint/src/levels.rs6
-rw-r--r--compiler/rustc_lint/src/non_fmt_panic.rs3
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs2
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs4
-rw-r--r--compiler/rustc_mir_transform/src/early_otherwise_branch.rs2
-rw-r--r--compiler/rustc_mir_transform/src/normalize_array_len.rs3
-rw-r--r--compiler/rustc_passes/src/check_attr.rs3
-rw-r--r--compiler/rustc_resolve/src/imports.rs9
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs6
-rw-r--r--compiler/rustc_traits/src/chalk/lowering.rs2
-rw-r--r--compiler/rustc_typeck/src/check/callee.rs2
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs45
-rw-r--r--compiler/rustc_typeck/src/check/regionck.rs2
-rw-r--r--library/alloc/src/lib.rs7
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--src/librustdoc/html/highlight.rs23
-rw-r--r--src/librustdoc/html/highlight/fixtures/sample.html6
-rw-r--r--src/librustdoc/html/highlight/fixtures/sample.rs2
-rw-r--r--src/librustdoc/json/conversions.rs1
-rw-r--r--src/librustdoc/json/mod.rs4
-rw-r--r--src/rustdoc-json-types/lib.rs2
-rw-r--r--src/test/rustdoc-json/primitives.rs22
-rw-r--r--src/test/rustdoc/macro_rules-matchers.rs18
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr2
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr1
-rw-r--r--src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr2
-rw-r--r--src/test/ui/resolve/issue-85671.rs37
36 files changed, 166 insertions, 84 deletions
diff --git a/compiler/rustc_ast/src/lib.rs b/compiler/rustc_ast/src/lib.rs
index a6167773003..e3c610585d9 100644
--- a/compiler/rustc_ast/src/lib.rs
+++ b/compiler/rustc_ast/src/lib.rs
@@ -20,16 +20,6 @@
 #[macro_use]
 extern crate rustc_macros;
 
-#[macro_export]
-macro_rules! unwrap_or {
-    ($opt:expr, $default:expr) => {
-        match $opt {
-            Some(x) => x,
-            None => $default,
-        }
-    };
-}
-
 pub mod util {
     pub mod classify;
     pub mod comments;
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index ea9eb0cf274..a5a4de81f12 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1345,8 +1345,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         generics
                             .params
                             .iter()
-                            .find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
-                            .is_some()
+                            .any(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
                     }
                     // Either the `bounded_ty` is not a plain type parameter, or
                     // it's not found in the generic type parameters list.
diff --git a/compiler/rustc_borrowck/src/dataflow.rs b/compiler/rustc_borrowck/src/dataflow.rs
index 1e660ece908..7db8d4520d4 100644
--- a/compiler/rustc_borrowck/src/dataflow.rs
+++ b/compiler/rustc_borrowck/src/dataflow.rs
@@ -201,7 +201,7 @@ impl<'tcx> OutOfScopePrecomputer<'_, 'tcx> {
                 let bb_data = &self.body[bb];
                 debug_assert!(hi == bb_data.statements.len());
                 for &succ_bb in bb_data.terminator().successors() {
-                    if self.visited.insert(succ_bb) == false {
+                    if !self.visited.insert(succ_bb) {
                         if succ_bb == location.block && first_lo > 0 {
                             // `succ_bb` has been seen before. If it wasn't
                             // fully processed, add its first part to `stack`
diff --git a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
index 7ca72cbed8d..246d2e3208c 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
@@ -972,8 +972,7 @@ fn suggest_ampmut<'tcx>(
     if let Some(assignment_rhs_span) = opt_assignment_rhs_span {
         if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
             let is_mutbl = |ty: &str| -> bool {
-                if ty.starts_with("mut") {
-                    let rest = &ty[3..];
+                if let Some(rest) = ty.strip_prefix("mut") {
                     match rest.chars().next() {
                         // e.g. `&mut x`
                         Some(c) if c.is_whitespace() => true,
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 0f88995846c..cd78c016caa 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -594,7 +594,7 @@ impl<'a> TraitDef<'a> {
             GenericParamKind::Const { ty, kw_span, .. } => {
                 let const_nodefault_kind = GenericParamKind::Const {
                     ty: ty.clone(),
-                    kw_span: kw_span.clone(),
+                    kw_span: *kw_span,
 
                     // We can't have default values inside impl block
                     default: None,
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index 43aa8a6efce..0efe5a56436 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -130,8 +130,8 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             .tcx()
             .sess
             .struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
-        err.span_label(impl_sp, &format!("found"));
-        err.span_label(trait_sp, &format!("expected"));
+        err.span_label(impl_sp, "found");
+        err.span_label(trait_sp, "expected");
 
         err.emit();
     }
diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs
index 66966e589e4..b6d66eb12d0 100644
--- a/compiler/rustc_lint/src/levels.rs
+++ b/compiler/rustc_lint/src/levels.rs
@@ -1,7 +1,6 @@
 use crate::context::{CheckLintNameResult, LintStore};
 use crate::late::unerased_lint_store;
 use rustc_ast as ast;
-use rustc_ast::unwrap_or;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
@@ -233,7 +232,10 @@ impl<'s> LintLevelsBuilder<'s> {
                 Some(lvl) => lvl,
             };
 
-            let mut metas = unwrap_or!(attr.meta_item_list(), continue);
+            let mut metas = match attr.meta_item_list() {
+                Some(x) => x,
+                None => continue,
+            };
 
             if metas.is_empty() {
                 // FIXME (#55112): issue unused-attributes lint for `#[level()]`
diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs
index 103555a6752..f2ad72f97ec 100644
--- a/compiler/rustc_lint/src/non_fmt_panic.rs
+++ b/compiler/rustc_lint/src/non_fmt_panic.rs
@@ -230,8 +230,7 @@ fn check_panic_str<'tcx>(
         Err(_) => (None, None),
     };
 
-    let mut fmt_parser =
-        Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
+    let mut fmt_parser = Parser::new(fmt, style, snippet.clone(), false, ParseMode::Format);
     let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
 
     if n_arguments > 0 && fmt_parser.errors.is_empty() {
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index a7446765900..2431b819a3f 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -363,7 +363,7 @@ impl Collector<'tcx> {
                 .collect::<Vec<_>>();
             if existing.is_empty() {
                 // Add if not found
-                let new_name = passed_lib.new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
+                let new_name: Option<&str> = passed_lib.new_name.as_deref();
                 let lib = NativeLib {
                     name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))),
                     kind: passed_lib.kind,
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index fee13fd2e2e..0bdf70b3ec4 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -986,7 +986,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
                             let niche = if def.repr.hide_niche() {
                                 None
                             } else {
-                                Niche::from_scalar(dl, Size::ZERO, scalar.clone())
+                                Niche::from_scalar(dl, Size::ZERO, *scalar)
                             };
                             if let Some(niche) = niche {
                                 match st.largest_niche {
@@ -2273,7 +2273,7 @@ where
         ) -> TyMaybeWithLayout<'tcx> {
             let tcx = cx.tcx();
             let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
-                let layout = Layout::scalar(cx, tag.clone());
+                let layout = Layout::scalar(cx, tag);
                 TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) }
             };
 
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 1464ea58ad0..9a86d465f98 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -130,7 +130,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     TerminatorKind::Call {
                         func: exchange_malloc,
                         args: vec![Operand::Move(size), Operand::Move(align)],
-                        destination: Some((Place::from(storage), success)),
+                        destination: Some((storage, success)),
                         cleanup: None,
                         from_hir_call: false,
                         fn_span: expr_span,
@@ -153,7 +153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 }
 
                 // Transmute `*mut u8` to the box (thus far, uninitialized):
-                let box_ = Rvalue::ShallowInitBox(Operand::Move(Place::from(storage)), value.ty);
+                let box_ = Rvalue::ShallowInitBox(Operand::Move(storage), value.ty);
                 this.cfg.push_assign(block, source_info, Place::from(result), box_);
 
                 // initialize the box contents:
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index dfcbd0da3a6..9e961f7ba5d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -1068,9 +1068,7 @@ impl<'tcx> SplitWildcard<'tcx> {
                     Missing {
                         nonexhaustive_enum_missing_real_variants: self
                             .iter_missing(pcx)
-                            .filter(|c| !c.is_non_exhaustive())
-                            .next()
-                            .is_some(),
+                            .any(|c| !c.is_non_exhaustive()),
                     }
                 } else {
                     Missing { nonexhaustive_enum_missing_real_variants: false }
diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
index d7f1ad7f696..f191911a6c7 100644
--- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
+++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
@@ -263,7 +263,7 @@ impl<'a, 'tcx> Helper<'a, 'tcx> {
             }
 
             // check that the value being matched on is the same. The
-            if this_bb_discr_info.targets_with_values.iter().find(|x| x.0 == value).is_none() {
+            if !this_bb_discr_info.targets_with_values.iter().any(|x| x.0 == value) {
                 trace!("NO: values being matched on are not the same");
                 return None;
             }
diff --git a/compiler/rustc_mir_transform/src/normalize_array_len.rs b/compiler/rustc_mir_transform/src/normalize_array_len.rs
index 60e71130cd1..76f0e83c8c3 100644
--- a/compiler/rustc_mir_transform/src/normalize_array_len.rs
+++ b/compiler/rustc_mir_transform/src/normalize_array_len.rs
@@ -111,8 +111,7 @@ impl<'a, 'tcx> Patcher<'a, 'tcx> {
                         Operand::Copy(place) | Operand::Move(place) => {
                             // create new local
                             let ty = operand.ty(self.local_decls, self.tcx);
-                            let local_decl =
-                                LocalDecl::with_source_info(ty, statement.source_info.clone());
+                            let local_decl = LocalDecl::with_source_info(ty, statement.source_info);
                             let local = self.local_decls.push(local_decl);
                             // make it live
                             let mut make_live_statement = statement.clone();
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 1815302101f..e5fbddda744 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1767,8 +1767,7 @@ impl CheckAttrVisitor<'tcx> {
     fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
         if target != Target::MacroDef {
             self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
-                lint.build(&format!("`#[macro_export]` only has an effect on macro definitions"))
-                    .emit();
+                lint.build("`#[macro_export]` only has an effect on macro definitions").emit();
             });
         }
     }
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 9be568b2cf1..515b2c3fd27 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -9,7 +9,6 @@ use crate::{BindingKey, ModuleKind, ResolutionError, Resolver, Segment};
 use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak};
 use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
 
-use rustc_ast::unwrap_or;
 use rustc_ast::NodeId;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::ptr_key::PtrKey;
@@ -349,10 +348,10 @@ impl<'a> Resolver<'a> {
             if !self.is_accessible_from(single_import.vis.get(), parent_scope.module) {
                 continue;
             }
-            let module = unwrap_or!(
-                single_import.imported_module.get(),
-                return Err((Undetermined, Weak::No))
-            );
+            let module = match single_import.imported_module.get() {
+                Some(x) => x,
+                None => return Err((Undetermined, Weak::No)),
+            };
             let ident = match single_import.kind {
                 ImportKind::Single { source, .. } => source,
                 _ => unreachable!(),
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index 25ec9682d84..1193d10d6a7 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -278,14 +278,14 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
 
             fn visit_expr(&mut self, expr: &thir::Expr<'tcx>) {
                 self.is_poly |= expr.ty.definitely_has_param_types_or_consts(self.tcx);
-                if self.is_poly == false {
+                if !self.is_poly {
                     visit::walk_expr(self, expr)
                 }
             }
 
             fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) {
                 self.is_poly |= pat.ty.definitely_has_param_types_or_consts(self.tcx);
-                if self.is_poly == false {
+                if !self.is_poly {
                     visit::walk_pat(self, pat);
                 }
             }
@@ -298,7 +298,7 @@ impl<'a, 'tcx> AbstractConstBuilder<'a, 'tcx> {
         let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body, tcx };
         visit::walk_expr(&mut is_poly_vis, &body[body_id]);
         debug!("AbstractConstBuilder: is_poly={}", is_poly_vis.is_poly);
-        if is_poly_vis.is_poly == false {
+        if !is_poly_vis.is_poly {
             return Ok(None);
         }
 
diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs
index 1d4196e5747..e24f699adf6 100644
--- a/compiler/rustc_traits/src/chalk/lowering.rs
+++ b/compiler/rustc_traits/src/chalk/lowering.rs
@@ -892,7 +892,7 @@ impl<'tcx> TypeVisitor<'tcx> for BoundVarsCollector<'tcx> {
         match r {
             ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
                 ty::BoundRegionKind::BrNamed(def_id, _name) => {
-                    if self.named_parameters.iter().find(|d| **d == def_id).is_none() {
+                    if !self.named_parameters.iter().any(|d| *d == def_id) {
                         self.named_parameters.push(def_id);
                     }
                 }
diff --git a/compiler/rustc_typeck/src/check/callee.rs b/compiler/rustc_typeck/src/check/callee.rs
index 4ffb061f7b4..51bbcbebcdc 100644
--- a/compiler/rustc_typeck/src/check/callee.rs
+++ b/compiler/rustc_typeck/src/check/callee.rs
@@ -329,7 +329,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let obligation = Obligation::new(
                             ObligationCause::dummy_with_span(callee_expr.span),
                             self.param_env,
-                            predicate.clone(),
+                            *predicate,
                         );
                         let result = self.infcx.evaluate_obligation(&obligation);
                         self.tcx
diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs
index 44d6f076f5d..6eeb28e32f1 100644
--- a/compiler/rustc_typeck/src/check/method/probe.rs
+++ b/compiler/rustc_typeck/src/check/method/probe.rs
@@ -753,17 +753,27 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
             let impl_ty = impl_ty.subst(self.tcx, impl_substs);
 
+            debug!("impl_ty: {:?}", impl_ty);
+
             // Determine the receiver type that the method itself expects.
-            let xform_tys = self.xform_self_ty(&item, impl_ty, impl_substs);
+            let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(&item, impl_ty, impl_substs);
+            debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
 
             // We can't use normalize_associated_types_in as it will pollute the
             // fcx's fulfillment context after this probe is over.
+            // Note: we only normalize `xform_self_ty` here since the normalization
+            // of the return type can lead to inference results that prohibit
+            // valid canidates from being found, see issue #85671
+            // FIXME Postponing the normalization of the return type likely only hides a deeper bug,
+            // which might be caused by the `param_env` itself. The clauses of the `param_env`
+            // maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
+            // see isssue #89650
             let cause = traits::ObligationCause::misc(self.span, self.body_id);
             let selcx = &mut traits::SelectionContext::new(self.fcx);
-            let traits::Normalized { value: (xform_self_ty, xform_ret_ty), obligations } =
-                traits::normalize(selcx, self.param_env, cause, xform_tys);
+            let traits::Normalized { value: xform_self_ty, obligations } =
+                traits::normalize(selcx, self.param_env, cause, xform_self_ty);
             debug!(
-                "assemble_inherent_impl_probe: xform_self_ty = {:?}/{:?}",
+                "assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}",
                 xform_self_ty, xform_ret_ty
             );
 
@@ -1420,6 +1430,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             };
 
             let mut result = ProbeResult::Match;
+            let mut xform_ret_ty = probe.xform_ret_ty;
+            debug!(?xform_ret_ty);
+
             let selcx = &mut traits::SelectionContext::new(self);
             let cause = traits::ObligationCause::misc(self.span, self.body_id);
 
@@ -1428,7 +1441,17 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             // match as well (or at least may match, sometimes we
             // don't have enough information to fully evaluate).
             match probe.kind {
-                InherentImplCandidate(substs, ref ref_obligations) => {
+                InherentImplCandidate(ref substs, ref ref_obligations) => {
+                    // `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
+                    // see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
+                    // for why this is necessary
+                    let traits::Normalized {
+                        value: normalized_xform_ret_ty,
+                        obligations: normalization_obligations,
+                    } = traits::normalize(selcx, self.param_env, cause.clone(), probe.xform_ret_ty);
+                    xform_ret_ty = normalized_xform_ret_ty;
+                    debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
+
                     // Check whether the impl imposes obligations we have to worry about.
                     let impl_def_id = probe.item.container.id();
                     let impl_bounds = self.tcx.predicates_of(impl_def_id);
@@ -1442,7 +1465,9 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
                     let candidate_obligations = impl_obligations
                         .chain(norm_obligations.into_iter())
-                        .chain(ref_obligations.iter().cloned());
+                        .chain(ref_obligations.iter().cloned())
+                        .chain(normalization_obligations.into_iter());
+
                     // Evaluate those obligations to see if they might possibly hold.
                     for o in candidate_obligations {
                         let o = self.resolve_vars_if_possible(o);
@@ -1527,9 +1552,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
             }
 
             if let ProbeResult::Match = result {
-                if let (Some(return_ty), Some(xform_ret_ty)) =
-                    (self.return_type, probe.xform_ret_ty)
-                {
+                if let (Some(return_ty), Some(xform_ret_ty)) = (self.return_type, xform_ret_ty) {
                     let xform_ret_ty = self.resolve_vars_if_possible(xform_ret_ty);
                     debug!(
                         "comparing return_ty {:?} with xform ret ty {:?}",
@@ -1669,6 +1692,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         self.static_candidates.push(source);
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn xform_self_ty(
         &self,
         item: &ty::AssocItem,
@@ -1683,9 +1707,10 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn xform_method_sig(&self, method: DefId, substs: SubstsRef<'tcx>) -> ty::FnSig<'tcx> {
         let fn_sig = self.tcx.fn_sig(method);
-        debug!("xform_self_ty(fn_sig={:?}, substs={:?})", fn_sig, substs);
+        debug!(?fn_sig);
 
         assert!(!substs.has_escaping_bound_vars());
 
diff --git a/compiler/rustc_typeck/src/check/regionck.rs b/compiler/rustc_typeck/src/check/regionck.rs
index 693246a3433..79443010fbb 100644
--- a/compiler/rustc_typeck/src/check/regionck.rs
+++ b/compiler/rustc_typeck/src/check/regionck.rs
@@ -413,7 +413,7 @@ impl<'a, 'tcx> Visitor<'tcx> for RegionCtxt<'a, 'tcx> {
             }
 
             hir::ExprKind::Match(ref discr, arms, _) => {
-                self.link_match(discr, &arms[..]);
+                self.link_match(discr, arms);
 
                 intravisit::walk_expr(self, expr);
             }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 72fe84222de..dd04f782f94 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -69,7 +69,12 @@
 )]
 #![cfg_attr(
     not(bootstrap),
-    doc(cfg_hide(not(test), not(any(test, bootstrap)), target_has_atomic = "ptr"))
+    doc(cfg_hide(
+        not(test),
+        not(any(test, bootstrap)),
+        any(not(feature = "miri-test-libstd"), test, doctest),
+        target_has_atomic = "ptr"
+    ))
 )]
 #![no_std]
 #![needs_allocator]
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 630876445ba..e10d01b58b0 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -64,6 +64,7 @@
     not(bootstrap),
     doc(cfg_hide(
         not(test),
+        any(not(feature = "miri-test-libstd"), test, doctest),
         target_pointer_width = "16",
         target_pointer_width = "32",
         target_pointer_width = "64",
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 43d1b8f794c..8ed69962875 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -435,7 +435,27 @@ impl<'a> Classifier<'a> {
                 _ => Class::RefKeyWord,
             },
 
-            // Operators.
+            // These can either be operators, or arrows.
+            TokenKind::Eq => match lookahead {
+                Some(TokenKind::Eq) => {
+                    self.next();
+                    sink(Highlight::Token { text: "==", class: Some(Class::Op) });
+                    return;
+                }
+                Some(TokenKind::Gt) => {
+                    self.next();
+                    sink(Highlight::Token { text: "=>", class: None });
+                    return;
+                }
+                _ => Class::Op,
+            },
+            TokenKind::Minus if lookahead == Some(TokenKind::Gt) => {
+                self.next();
+                sink(Highlight::Token { text: "->", class: None });
+                return;
+            }
+
+            // Other operators.
             TokenKind::Minus
             | TokenKind::Plus
             | TokenKind::Or
@@ -443,7 +463,6 @@ impl<'a> Classifier<'a> {
             | TokenKind::Caret
             | TokenKind::Percent
             | TokenKind::Bang
-            | TokenKind::Eq
             | TokenKind::Lt
             | TokenKind::Gt => Class::Op,
 
diff --git a/src/librustdoc/html/highlight/fixtures/sample.html b/src/librustdoc/html/highlight/fixtures/sample.html
index 866caea9256..22e650af7e2 100644
--- a/src/librustdoc/html/highlight/fixtures/sample.html
+++ b/src/librustdoc/html/highlight/fixtures/sample.html
@@ -13,7 +13,7 @@
 <span class="kw">use</span> <span class="ident">std::path</span>::{<span class="ident">Path</span>, <span class="ident">PathBuf</span>};
 
 <span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">&quot;linux&quot;</span>)]</span>
-<span class="kw">fn</span> <span class="ident">main</span>() {
+<span class="kw">fn</span> <span class="ident">main</span>() -&gt; () {
     <span class="kw">let</span> <span class="ident">foo</span> <span class="op">=</span> <span class="bool-val">true</span> <span class="op">&amp;&amp;</span> <span class="bool-val">false</span> <span class="op">|</span><span class="op">|</span> <span class="bool-val">true</span>;
     <span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">*</span><span class="kw">const</span> () <span class="op">=</span> <span class="number">0</span>;
     <span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">&amp;</span><span class="ident">foo</span>;
@@ -27,11 +27,11 @@
     <span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">String::new</span>();
 
     <span class="kw">match</span> <span class="kw-2">&amp;</span><span class="ident">s</span> {
-        <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> <span class="op">=</span><span class="op">&gt;</span> {}
+        <span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> =&gt; {}
     }
 }
 
 <span class="macro">macro_rules!</span> <span class="ident">bar</span> {
-    (<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) <span class="op">=</span><span class="op">&gt;</span> {};
+    (<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) =&gt; {};
 }
 </code></pre>
diff --git a/src/librustdoc/html/highlight/fixtures/sample.rs b/src/librustdoc/html/highlight/fixtures/sample.rs
index b027203655d..fbfdc676733 100644
--- a/src/librustdoc/html/highlight/fixtures/sample.rs
+++ b/src/librustdoc/html/highlight/fixtures/sample.rs
@@ -3,7 +3,7 @@
 use std::path::{Path, PathBuf};
 
 #[cfg(target_os = "linux")]
-fn main() {
+fn main() -> () {
     let foo = true && false || true;
     let _: *const () = 0;
     let _ = &foo;
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 731fc4ff3ce..661453521d1 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -418,7 +418,6 @@ impl FromWithTcx<clean::Type> for Type {
                 }
             }
             Generic(s) => Type::Generic(s.to_string()),
-            Primitive(clean::PrimitiveType::Never) => Type::Never,
             Primitive(p) => Type::Primitive(p.as_sym().to_string()),
             BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
             Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()),
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index 040a880ace9..637e5f2288d 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -207,7 +207,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
         debug!("Done with crate");
 
         for primitive in Rc::clone(&self.cache).primitive_locations.values() {
-            self.get_impls(primitive.clone());
+            self.get_impls(*primitive);
         }
 
         let mut index = (*self.index).clone().into_inner();
@@ -255,7 +255,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
                     )
                 })
                 .collect(),
-            format_version: 8,
+            format_version: 9,
         };
         let mut p = self.out_path.clone();
         p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs
index 22debd296c2..7c418697c1c 100644
--- a/src/rustdoc-json-types/lib.rs
+++ b/src/rustdoc-json-types/lib.rs
@@ -388,8 +388,6 @@ pub enum Type {
     },
     /// `impl TraitA + TraitB + ...`
     ImplTrait(Vec<GenericBound>),
-    /// `!`
-    Never,
     /// `_`
     Infer,
     /// `*mut u32`, `*u8`, etc.
diff --git a/src/test/rustdoc-json/primitives.rs b/src/test/rustdoc-json/primitives.rs
new file mode 100644
index 00000000000..fd04f04da06
--- /dev/null
+++ b/src/test/rustdoc-json/primitives.rs
@@ -0,0 +1,22 @@
+#![feature(never_type)]
+
+// @has primitives.json "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
+// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
+pub type PrimNever = !;
+
+// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
+pub type PrimStr = str;
+
+// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
+pub type PrimBool = bool;
+
+// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
+pub type PrimChar = char;
+
+// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
+// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
+pub type PrimU8 = u8;
diff --git a/src/test/rustdoc/macro_rules-matchers.rs b/src/test/rustdoc/macro_rules-matchers.rs
index 5f8340e7312..efc3b21e6da 100644
--- a/src/test/rustdoc/macro_rules-matchers.rs
+++ b/src/test/rustdoc/macro_rules-matchers.rs
@@ -6,37 +6,31 @@
 // @has 'foo/macro.todo.html'
 // @has - '//span[@class="macro"]' 'macro_rules!'
 // @has - '//span[@class="ident"]' 'todo'
-// Note: count = 2 * ('=' + '>') + '+' = 2 * (1 + 1) + 1 = 5
-// @count - '//pre[@class="rust macro"]//span[@class="op"]' 5
+// Note: the only op is the `+`
+// @count - '//pre[@class="rust macro"]//span[@class="op"]' 1
 
-// @has - '{ ()'
-// @has - '//span[@class="op"]' '='
-// @has - '//span[@class="op"]' '>'
-// @has - '{ ... };'
-
-// @has - '($('
+// @has - '{ () =&gt; { ... }; ($('
 // @has - '//span[@class="macro-nonterminal"]' '$'
 // @has - '//span[@class="macro-nonterminal"]' 'arg'
 // @has - ':'
 // @has - '//span[@class="ident"]' 'tt'
 // @has - '),'
 // @has - '//span[@class="op"]' '+'
-// @has - ')'
+// @has - ') =&gt; { ... }; }'
 pub use std::todo;
 
 mod mod1 {
     // @has 'foo/macro.macro1.html'
     // @has - 'macro_rules!'
     // @has - 'macro1'
-    // @has - '{ ()'
-    // @has - '($('
+    // @has - '{ () =&gt; { ... }; ($('
     // @has - '//span[@class="macro-nonterminal"]' '$'
     // @has - '//span[@class="macro-nonterminal"]' 'arg'
     // @has - ':'
     // @has - 'expr'
     // @has - '),'
     // @has - '+'
-    // @has - ')'
+    // @has - ') =&gt; { ... }; }'
     #[macro_export]
     macro_rules! macro1 {
         () => {};
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
index 21fc3b2bdd1..ce8173169b1 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref.stderr
@@ -6,7 +6,6 @@ LL |     let _result = &Some(42).as_deref();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: Deref`
-           `<{integer} as Deref>::Target = _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
index c86b024de21..e4e9705b07d 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/option-as_deref_mut.stderr
@@ -6,7 +6,7 @@ LL |     let _result = &mut Some(42).as_deref_mut();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: DerefMut`
-           `<{integer} as Deref>::Target = _`
+           `{integer}: Deref`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
index 9711e27d8a8..a3b9ac67758 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref.stderr
@@ -6,7 +6,6 @@ LL |     let _result = &Ok(42).as_deref();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: Deref`
-           `<{integer} as Deref>::Target = _`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
index ee7ea1e6a02..98a7091dd05 100644
--- a/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
+++ b/src/test/ui/issues/issue-50264-inner-deref-trait/result-as_deref_mut.stderr
@@ -6,7 +6,7 @@ LL |     let _result = &mut Ok(42).as_deref_mut();
    |
    = note: the following trait bounds were not satisfied:
            `{integer}: DerefMut`
-           `<{integer} as Deref>::Target = _`
+           `{integer}: Deref`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/resolve/issue-85671.rs b/src/test/ui/resolve/issue-85671.rs
new file mode 100644
index 00000000000..337ec307ef3
--- /dev/null
+++ b/src/test/ui/resolve/issue-85671.rs
@@ -0,0 +1,37 @@
+// check-pass
+
+// Some trait with a function that returns a slice:
+pub trait AsSlice {
+    type Element;
+    fn as_slice(&self) -> &[Self::Element];
+}
+
+// Some type
+pub struct A<Cont>(Cont);
+
+// Here we say that if A wraps a slice, then it implements AsSlice
+impl<'a, Element> AsSlice for A<&'a [Element]> {
+    type Element = Element;
+    fn as_slice(&self) -> &[Self::Element] {
+        self.0
+    }
+}
+
+impl<Cont> A<Cont> {
+    // We want this function to work
+    pub fn failing<Coef>(&self)
+    where
+        Self: AsSlice<Element = Coef>,
+    {
+        self.as_ref_a().as_ref_a();
+    }
+
+    pub fn as_ref_a<Coef>(&self) -> A<&[<Self as AsSlice>::Element]>
+    where
+        Self: AsSlice<Element = Coef>,
+    {
+        A(self.as_slice())
+    }
+}
+
+fn main() {}