about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-08-31 11:20:32 +0000
committerbors <bors@rust-lang.org>2021-08-31 11:20:32 +0000
commit76d18cfb8945f824c8777e04981e930d2037954e (patch)
tree9f4dba058543f58edd2637684793081670592a2d
parentfe37929e4cba2c5c21e6805805769630c736bc3d (diff)
parentfeafda8cd3f98e5ebb0a2637918180722dec4799 (diff)
downloadrust-76d18cfb8945f824c8777e04981e930d2037954e.tar.gz
rust-76d18cfb8945f824c8777e04981e930d2037954e.zip
Auto merge of #88527 - m-ou-se:rollup-az6xtc5, r=m-ou-se
Rollup of 14 pull requests

Successful merges:

 - #88394 (Document `std::env::current_exe` possible rename behaviour)
 - #88406 (Tait nest infer test)
 - #88408 (Add inference cycle TAIT test)
 - #88409 (Add auto trait leakage TAIT test)
 - #88413 (Add weird return types TAIT test)
 - #88450 (fix(rustc_parse): correct span in `maybe_whole_expr!`)
 - #88462 (rustdoc: Stop using resolver for macro loading)
 - #88465 (Adding examples to docs of `std::time` module)
 - #88486 (Remove unused arena macro args)
 - #88492 (Use MaybeUninit::write in functor.rs)
 - #88496 (Fix prelude collision lint suggestion for generics with lifetimes)
 - #88497 (Fix prelude collision suggestions for glob imported traits. )
 - #88503 (Warn when [T; N].into_iter() is ambiguous in the new edition. )
 - #88509 (Don't suggest extra <> in dyn suggestion.)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--Cargo.lock1
-rw-r--r--compiler/rustc_arena/src/lib.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_data_structures/src/functor.rs2
-rw-r--r--compiler/rustc_hir/src/arena.rs4
-rw-r--r--compiler/rustc_lint/src/lib.rs2
-rw-r--r--compiler/rustc_middle/src/arena.rs6
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs6
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs4
-rw-r--r--compiler/rustc_typeck/Cargo.toml1
-rw-r--r--compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs15
-rw-r--r--compiler/rustc_typeck/src/check/method/prelude2021.rs98
-rw-r--r--library/core/src/time.rs17
-rw-r--r--library/std/src/env.rs3
-rw-r--r--library/std/src/time.rs31
-rw-r--r--src/librustdoc/clean/inline.rs6
-rw-r--r--src/test/ui/dyn-keyword/dyn-angle-brackets.fixed23
-rw-r--r--src/test/ui/dyn-keyword/dyn-angle-brackets.rs23
-rw-r--r--src/test/ui/dyn-keyword/dyn-angle-brackets.stderr25
-rw-r--r--src/test/ui/parser/issue-87812-path.rs11
-rw-r--r--src/test/ui/parser/issue-87812-path.stderr16
-rw-r--r--src/test/ui/parser/issue-87812.rs13
-rw-r--r--src/test/ui/parser/issue-87812.stderr22
-rw-r--r--src/test/ui/rust-2021/array-into-iter-ambiguous.fixed27
-rw-r--r--src/test/ui/rust-2021/array-into-iter-ambiguous.rs27
-rw-r--r--src/test/ui/rust-2021/array-into-iter-ambiguous.stderr16
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed30
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs30
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr16
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.fixed16
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.rs14
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-generic.stderr10
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.fixed11
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.rs11
-rw-r--r--src/test/ui/rust-2021/future-prelude-collision-imported.stderr11
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr20
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs21
-rw-r--r--src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr22
-rw-r--r--src/test/ui/type-alias-impl-trait/inference-cycle.rs26
-rw-r--r--src/test/ui/type-alias-impl-trait/inference-cycle.stderr37
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference.rs18
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs19
-rw-r--r--src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr19
-rw-r--r--src/test/ui/type-alias-impl-trait/weird-return-types.rs16
46 files changed, 698 insertions, 89 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7a6e88f0b8b..1dfe710ecee 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4405,6 +4405,7 @@ dependencies = [
  "rustc_hir_pretty",
  "rustc_index",
  "rustc_infer",
+ "rustc_lint",
  "rustc_macros",
  "rustc_middle",
  "rustc_session",
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index 2e8022d9880..6d5f47aceeb 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -635,7 +635,7 @@ pub macro which_arena_for_type {
 }
 
 #[rustc_macro_transparency = "semitransparent"]
-pub macro declare_arena([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
+pub macro declare_arena([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) {
     #[derive(Default)]
     pub struct Arena<$tcx> {
         pub dropless: $crate::DroplessArena,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index b71fcb7a349..0133acfee10 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -84,7 +84,7 @@ mod path;
 
 const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF;
 
-rustc_hir::arena_types!(rustc_arena::declare_arena, [], 'tcx);
+rustc_hir::arena_types!(rustc_arena::declare_arena, 'tcx);
 
 struct LoweringContext<'a, 'hir: 'a> {
     /// Used to assign IDs to HIR nodes that do not directly correspond to AST nodes.
diff --git a/compiler/rustc_data_structures/src/functor.rs b/compiler/rustc_data_structures/src/functor.rs
index fe7a256d210..5b83ae31247 100644
--- a/compiler/rustc_data_structures/src/functor.rs
+++ b/compiler/rustc_data_structures/src/functor.rs
@@ -26,7 +26,7 @@ impl<T> IdFunctor for Box<T> {
             // inverse of `Box::assume_init()` and should be safe.
             let mut raw: Box<mem::MaybeUninit<T>> = Box::from_raw(raw.cast());
             // SAFETY: Write the mapped value back into the `Box`.
-            ptr::write(raw.as_mut_ptr(), f(value));
+            raw.write(f(value));
             // SAFETY: We just initialized `raw`.
             raw.assume_init()
         }
diff --git a/compiler/rustc_hir/src/arena.rs b/compiler/rustc_hir/src/arena.rs
index 0801a1bde22..3e8b98e9f54 100644
--- a/compiler/rustc_hir/src/arena.rs
+++ b/compiler/rustc_hir/src/arena.rs
@@ -9,8 +9,8 @@
 /// where `T` is the type listed. These impls will appear in the implement_ty_decoder! macro.
 #[macro_export]
 macro_rules! arena_types {
-    ($macro:path, $args:tt, $tcx:lifetime) => (
-        $macro!($args, [
+    ($macro:path, $tcx:lifetime) => (
+        $macro!([
             // HIR types
             [few] hir_krate: rustc_hir::Crate<$tcx>,
             [] arm: rustc_hir::Arm<$tcx>,
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 24ac723f2c9..ef4bda666ba 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -62,6 +62,8 @@ mod traits;
 mod types;
 mod unused;
 
+pub use array_into_iter::ARRAY_INTO_ITER;
+
 use rustc_ast as ast;
 use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index a89d00e26ac..59db2c6636f 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -9,8 +9,8 @@
 /// listed. These impls will appear in the implement_ty_decoder! macro.
 #[macro_export]
 macro_rules! arena_types {
-    ($macro:path, $args:tt, $tcx:lifetime) => (
-        $macro!($args, [
+    ($macro:path, $tcx:lifetime) => (
+        $macro!([
             [] layouts: rustc_target::abi::Layout,
             // AdtDef are interned and compared by address
             [] adt_def: rustc_middle::ty::AdtDef,
@@ -109,4 +109,4 @@ macro_rules! arena_types {
     )
 }
 
-arena_types!(rustc_arena::declare_arena, [], 'tcx);
+arena_types!(rustc_arena::declare_arena, 'tcx);
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 36db258e92d..4edb6a327b0 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -437,15 +437,15 @@ macro_rules! impl_arena_allocatable_decoder {
 }
 
 macro_rules! impl_arena_allocatable_decoders {
-    ([], [$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
+    ([$($a:tt $name:ident: $ty:ty,)*], $tcx:lifetime) => {
         $(
             impl_arena_allocatable_decoder!($a [[$name: $ty], $tcx]);
         )*
     }
 }
 
-rustc_hir::arena_types!(impl_arena_allocatable_decoders, [], 'tcx);
-arena_types!(impl_arena_allocatable_decoders, [], 'tcx);
+rustc_hir::arena_types!(impl_arena_allocatable_decoders, 'tcx);
+arena_types!(impl_arena_allocatable_decoders, 'tcx);
 
 #[macro_export]
 macro_rules! implement_ty_decoder {
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index e71edbc861a..a1d3e9adba0 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -41,7 +41,7 @@ macro_rules! maybe_whole_expr {
                     let path = path.clone();
                     $p.bump();
                     return Ok($p.mk_expr(
-                        $p.token.span,
+                        $p.prev_token.span,
                         ExprKind::Path(None, path),
                         AttrVec::new(),
                     ));
@@ -50,7 +50,7 @@ macro_rules! maybe_whole_expr {
                     let block = block.clone();
                     $p.bump();
                     return Ok($p.mk_expr(
-                        $p.token.span,
+                        $p.prev_token.span,
                         ExprKind::Block(block, None),
                         AttrVec::new(),
                     ));
diff --git a/compiler/rustc_typeck/Cargo.toml b/compiler/rustc_typeck/Cargo.toml
index fa5ef63f5c5..dd76a5e4b99 100644
--- a/compiler/rustc_typeck/Cargo.toml
+++ b/compiler/rustc_typeck/Cargo.toml
@@ -26,3 +26,4 @@ rustc_index = { path = "../rustc_index" }
 rustc_infer = { path = "../rustc_infer" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 rustc_ty_utils = { path = "../rustc_ty_utils" }
+rustc_lint = { path = "../rustc_lint" }
diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
index 25d1c8706e8..17e0c42440c 100644
--- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
+++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs
@@ -914,7 +914,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             });
 
         if result.is_ok() {
-            self.maybe_lint_bare_trait(qpath, hir_id);
+            self.maybe_lint_bare_trait(qpath, hir_id, span);
             self.register_wf_obligation(ty.into(), qself.span, traits::WellFormed(None));
         }
 
@@ -927,7 +927,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         )
     }
 
-    fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId) {
+    fn maybe_lint_bare_trait(&self, qpath: &QPath<'_>, hir_id: hir::HirId, span: Span) {
         if let QPath::TypeRelative(self_ty, _) = qpath {
             if let TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =
                 self_ty.kind
@@ -935,10 +935,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let msg = "trait objects without an explicit `dyn` are deprecated";
                 let (sugg, app) = match self.tcx.sess.source_map().span_to_snippet(self_ty.span) {
                     Ok(s) if poly_trait_ref.trait_ref.path.is_global() => {
-                        (format!("<dyn ({})>", s), Applicability::MachineApplicable)
+                        (format!("dyn ({})", s), Applicability::MachineApplicable)
                     }
-                    Ok(s) => (format!("<dyn {}>", s), Applicability::MachineApplicable),
-                    Err(_) => ("<dyn <type>>".to_string(), Applicability::HasPlaceholders),
+                    Ok(s) => (format!("dyn {}", s), Applicability::MachineApplicable),
+                    Err(_) => ("dyn <type>".to_string(), Applicability::HasPlaceholders),
+                };
+                // Wrap in `<..>` if it isn't already.
+                let sugg = match self.tcx.sess.source_map().span_to_snippet(span) {
+                    Ok(s) if s.starts_with('<') => sugg,
+                    _ => format!("<{}>", sugg),
                 };
                 let replace = String::from("use `dyn`");
                 if self.sess().edition() >= Edition::Edition2021 {
diff --git a/compiler/rustc_typeck/src/check/method/prelude2021.rs b/compiler/rustc_typeck/src/check/method/prelude2021.rs
index b5bc9d3599a..1347f56258e 100644
--- a/compiler/rustc_typeck/src/check/method/prelude2021.rs
+++ b/compiler/rustc_typeck/src/check/method/prelude2021.rs
@@ -5,9 +5,9 @@ use rustc_ast::Mutability;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_middle::ty::subst::InternalSubsts;
-use rustc_middle::ty::{Adt, Ref, Ty};
+use rustc_middle::ty::{Adt, Array, Ref, Ty};
 use rustc_session::lint::builtin::RUST_2021_PRELUDE_COLLISIONS;
-use rustc_span::symbol::kw::Underscore;
+use rustc_span::symbol::kw::{Empty, Underscore};
 use rustc_span::symbol::{sym, Ident};
 use rustc_span::Span;
 use rustc_trait_selection::infer::InferCtxtExt;
@@ -38,10 +38,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             return;
         }
 
-        // These are the method names that were added to prelude in Rust 2021
-        if !matches!(segment.ident.name, sym::try_into) {
-            return;
-        }
+        let prelude_or_array_lint = match segment.ident.name {
+            // `try_into` was added to the prelude in Rust 2021.
+            sym::try_into => RUST_2021_PRELUDE_COLLISIONS,
+            // `into_iter` wasn't added to the prelude,
+            // but `[T; N].into_iter()` doesn't resolve to IntoIterator::into_iter
+            // before Rust 2021, which results in the same problem.
+            // It is only a problem for arrays.
+            sym::into_iter if let Array(..) = self_ty.kind() => {
+                // In this case, it wasn't really a prelude addition that was the problem.
+                // Instead, the problem is that the array-into_iter hack will no longer apply in Rust 2021.
+                rustc_lint::ARRAY_INTO_ITER
+            }
+            _ => return,
+        };
 
         // No need to lint if method came from std/core, as that will now be in the prelude
         if matches!(self.tcx.crate_name(pick.item.def_id.krate), sym::std | sym::core) {
@@ -69,7 +79,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Inherent impls only require not relying on autoref and autoderef in order to
             // ensure that the trait implementation won't be used
             self.tcx.struct_span_lint_hir(
-                RUST_2021_PRELUDE_COLLISIONS,
+                prelude_or_array_lint,
                 self_expr.hir_id,
                 self_expr.span,
                 |lint| {
@@ -130,7 +140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // trait implementations require full disambiguation to not clash with the new prelude
             // additions (i.e. convert from dot-call to fully-qualified call)
             self.tcx.struct_span_lint_hir(
-                RUST_2021_PRELUDE_COLLISIONS,
+                prelude_or_array_lint,
                 call_expr.hir_id,
                 call_expr.span,
                 |lint| {
@@ -239,47 +249,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let trait_path = self.trait_path_or_bare_name(span, expr_id, pick.item.container.id());
             let trait_generics = self.tcx.generics_of(pick.item.container.id());
 
-            let parameter_count = trait_generics.count() - (trait_generics.has_self as usize);
-            let trait_name = if parameter_count == 0 {
-                trait_path
-            } else {
-                format!(
-                    "{}<{}>",
-                    trait_path,
-                    std::iter::repeat("_").take(parameter_count).collect::<Vec<_>>().join(", ")
-                )
-            };
+            let trait_name =
+                if trait_generics.params.len() <= trait_generics.has_self as usize {
+                    trait_path
+                } else {
+                    let counts = trait_generics.own_counts();
+                    format!(
+                        "{}<{}>",
+                        trait_path,
+                        std::iter::repeat("'_")
+                            .take(counts.lifetimes)
+                            .chain(std::iter::repeat("_").take(
+                                counts.types + counts.consts - trait_generics.has_self as usize
+                            ))
+                            .collect::<Vec<_>>()
+                            .join(", ")
+                    )
+                };
 
             let mut lint = lint.build(&format!(
                 "trait-associated function `{}` will become ambiguous in Rust 2021",
                 method_name.name
             ));
 
-            let self_ty_name = self
+            let mut self_ty_name = self
                 .sess()
                 .source_map()
                 .span_to_snippet(self_ty_span)
                 .unwrap_or_else(|_| self_ty.to_string());
 
-            let self_ty_generics_count = match self_ty.kind() {
-                // Get the number of generics the self type has (if an Adt) unless we can determine that
-                // the user has written the self type with generics already which we (naively) do by looking
-                // for a "<" in `self_ty_name`.
-                Adt(def, _) if !self_ty_name.contains('<') => self.tcx.generics_of(def.did).count(),
-                _ => 0,
-            };
-            let self_ty_generics = if self_ty_generics_count > 0 {
-                format!("<{}>", vec!["_"; self_ty_generics_count].join(", "))
-            } else {
-                String::new()
-            };
+            // Get the number of generics the self type has (if an Adt) unless we can determine that
+            // the user has written the self type with generics already which we (naively) do by looking
+            // for a "<" in `self_ty_name`.
+            if !self_ty_name.contains('<') {
+                if let Adt(def, _) = self_ty.kind() {
+                    let generics = self.tcx.generics_of(def.did);
+                    if !generics.params.is_empty() {
+                        let counts = generics.own_counts();
+                        self_ty_name += &format!(
+                            "<{}>",
+                            std::iter::repeat("'_")
+                                .take(counts.lifetimes)
+                                .chain(std::iter::repeat("_").take(counts.types + counts.consts))
+                                .collect::<Vec<_>>()
+                                .join(", ")
+                        );
+                    }
+                }
+            }
             lint.span_suggestion(
                 span,
                 "disambiguate the associated function",
-                format!(
-                    "<{}{} as {}>::{}",
-                    self_ty_name, self_ty_generics, trait_name, method_name.name,
-                ),
+                format!("<{} as {}>::{}", self_ty_name, trait_name, method_name.name,),
                 Applicability::MachineApplicable,
             );
 
@@ -322,7 +343,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .filter_map(|item| if item.ident.name != Underscore { Some(item.ident) } else { None })
             .next();
         if let Some(any_id) = any_id {
-            return Some(format!("{}", any_id));
+            if any_id.name == Empty {
+                // Glob import, so just use its name.
+                return None;
+            } else {
+                return Some(format!("{}", any_id));
+            }
         }
 
         // All that is left is `_`! We need to use the full path. It doesn't matter which one we pick,
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 2d8a1cb1ab0..35b740cd743 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -2,14 +2,21 @@
 
 //! Temporal quantification.
 //!
-//! Example:
+//! # Examples:
+//!
+//! There are multiple ways to create a new [`Duration`]:
 //!
 //! ```
-//! use std::time::Duration;
+//! # use std::time::Duration;
+//! let five_seconds = Duration::from_secs(5);
+//! assert_eq!(five_seconds, Duration::from_millis(5_000));
+//! assert_eq!(five_seconds, Duration::from_micros(5_000_000));
+//! assert_eq!(five_seconds, Duration::from_nanos(5_000_000_000));
 //!
-//! let five_seconds = Duration::new(5, 0);
-//! // both declarations are equivalent
-//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
+//! let ten_seconds = Duration::from_secs(10);
+//! let seven_nanos = Duration::from_nanos(7);
+//! let total = ten_seconds + seven_nanos;
+//! assert_eq!(total, Duration::new(10, 7));
 //! ```
 
 use crate::fmt;
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index a7465200955..e343073d215 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -616,6 +616,9 @@ pub fn temp_dir() -> PathBuf {
 /// return the path of the symbolic link and other platforms will return the
 /// path of the symbolic link’s target.
 ///
+/// If the executable is renamed while it is running, platforms may return the
+/// path at the time it was loaded instead of the new path.
+///
 /// # Errors
 ///
 /// Acquiring the path of the current executable is a platform-specific operation
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index ec105f231e5..e9207ee3617 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -1,13 +1,32 @@
 //! Temporal quantification.
 //!
-//! Example:
+//! # Examples:
 //!
+//! There are multiple ways to create a new [`Duration`]:
+//!
+//! ```
+//! # use std::time::Duration;
+//! let five_seconds = Duration::from_secs(5);
+//! assert_eq!(five_seconds, Duration::from_millis(5_000));
+//! assert_eq!(five_seconds, Duration::from_micros(5_000_000));
+//! assert_eq!(five_seconds, Duration::from_nanos(5_000_000_000));
+//!
+//! let ten_seconds = Duration::from_secs(10);
+//! let seven_nanos = Duration::from_nanos(7);
+//! let total = ten_seconds + seven_nanos;
+//! assert_eq!(total, Duration::new(10, 7));
 //! ```
-//! use std::time::Duration;
 //!
-//! let five_seconds = Duration::new(5, 0);
-//! // both declarations are equivalent
-//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
+//! Using [`Instant`] to calculate how long a function took to run:
+//!
+//! ```ignore (incomplete)
+//! let now = Instant::now();
+//!
+//! // Calling a slow function, it may take a while
+//! slow_function();
+//!
+//! let elapsed_time = now.elapsed();
+//! println!("Running slow_function() took {} seconds.", elapsed_time.as_secs());
 //! ```
 
 #![stable(feature = "time", since = "1.3.0")]
@@ -26,7 +45,7 @@ use crate::sys_common::FromInner;
 pub use core::time::Duration;
 
 /// A measurement of a monotonically nondecreasing clock.
-/// Opaque and useful only with `Duration`.
+/// Opaque and useful only with [`Duration`].
 ///
 /// Instants are always guaranteed to be no less than any previously measured
 /// instant when created, and are often useful for tasks such as measuring
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index fa29b542649..0c81a558430 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -9,7 +9,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::Mutability;
-use rustc_metadata::creader::LoadedMacro;
+use rustc_metadata::creader::{CStore, LoadedMacro};
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Symbol};
@@ -179,7 +179,7 @@ crate fn record_extern_fqn(cx: &mut DocContext<'_>, did: DefId, kind: ItemType)
     let fqn = if let ItemType::Macro = kind {
         // Check to see if it is a macro 2.0 or built-in macro
         if matches!(
-            cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())),
+            CStore::from_tcx(cx.tcx).load_macro_untracked(did, cx.sess()),
             LoadedMacro::MacroDef(def, _)
                 if matches!(&def.kind, ast::ItemKind::MacroDef(ast_def)
                     if !ast_def.macro_rules)
@@ -558,7 +558,7 @@ fn build_macro(
     import_def_id: Option<DefId>,
 ) -> clean::ItemKind {
     let imported_from = cx.tcx.crate_name(def_id.krate);
-    match cx.enter_resolver(|r| r.cstore().load_macro_untracked(def_id, cx.sess())) {
+    match CStore::from_tcx(cx.tcx).load_macro_untracked(def_id, cx.sess()) {
         LoadedMacro::MacroDef(item_def, _) => {
             if let ast::ItemKind::MacroDef(ref def) = item_def.kind {
                 clean::MacroItem(clean::Macro {
diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed
new file mode 100644
index 00000000000..25caa6a8030
--- /dev/null
+++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.fixed
@@ -0,0 +1,23 @@
+// See https://github.com/rust-lang/rust/issues/88508
+// run-rustfix
+// edition:2018
+#![deny(bare_trait_objects)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+use std::fmt;
+
+#[derive(Debug)]
+pub struct Foo;
+
+impl fmt::Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        <dyn fmt::Debug>::fmt(self, f)
+        //~^ ERROR trait objects without an explicit `dyn` are deprecated
+        //~| WARNING this is accepted in the current edition
+        //~| ERROR trait objects without an explicit `dyn` are deprecated
+        //~| WARNING this is accepted in the current edition
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.rs b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs
new file mode 100644
index 00000000000..cf72da2b61e
--- /dev/null
+++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.rs
@@ -0,0 +1,23 @@
+// See https://github.com/rust-lang/rust/issues/88508
+// run-rustfix
+// edition:2018
+#![deny(bare_trait_objects)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+use std::fmt;
+
+#[derive(Debug)]
+pub struct Foo;
+
+impl fmt::Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        <fmt::Debug>::fmt(self, f)
+        //~^ ERROR trait objects without an explicit `dyn` are deprecated
+        //~| WARNING this is accepted in the current edition
+        //~| ERROR trait objects without an explicit `dyn` are deprecated
+        //~| WARNING this is accepted in the current edition
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
new file mode 100644
index 00000000000..ef0f5b7f59d
--- /dev/null
+++ b/src/test/ui/dyn-keyword/dyn-angle-brackets.stderr
@@ -0,0 +1,25 @@
+error: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/dyn-angle-brackets.rs:15:10
+   |
+LL |         <fmt::Debug>::fmt(self, f)
+   |          ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug`
+   |
+note: the lint level is defined here
+  --> $DIR/dyn-angle-brackets.rs:4:9
+   |
+LL | #![deny(bare_trait_objects)]
+   |         ^^^^^^^^^^^^^^^^^^
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: trait objects without an explicit `dyn` are deprecated
+  --> $DIR/dyn-angle-brackets.rs:15:10
+   |
+LL |         <fmt::Debug>::fmt(self, f)
+   |          ^^^^^^^^^^ help: use `dyn`: `dyn fmt::Debug`
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/parser/issue-87812-path.rs b/src/test/ui/parser/issue-87812-path.rs
new file mode 100644
index 00000000000..b88780876db
--- /dev/null
+++ b/src/test/ui/parser/issue-87812-path.rs
@@ -0,0 +1,11 @@
+macro_rules! foo {
+    ( $f:path ) => {{
+        let _: usize = $f; //~ERROR
+    }};
+}
+
+struct Baz;
+
+fn main() {
+    foo!(Baz);
+}
diff --git a/src/test/ui/parser/issue-87812-path.stderr b/src/test/ui/parser/issue-87812-path.stderr
new file mode 100644
index 00000000000..0c8e6fdd307
--- /dev/null
+++ b/src/test/ui/parser/issue-87812-path.stderr
@@ -0,0 +1,16 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-87812-path.rs:3:24
+   |
+LL |         let _: usize = $f;
+   |                -----   ^^ expected `usize`, found struct `Baz`
+   |                |
+   |                expected due to this
+...
+LL |     foo!(Baz);
+   |     ---------- in this macro invocation
+   |
+   = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/parser/issue-87812.rs b/src/test/ui/parser/issue-87812.rs
new file mode 100644
index 00000000000..0ba87b99544
--- /dev/null
+++ b/src/test/ui/parser/issue-87812.rs
@@ -0,0 +1,13 @@
+#![deny(break_with_label_and_loop)]
+
+macro_rules! foo {
+    ( $f:block ) => {
+        '_l: loop {
+            break '_l $f; //~ERROR
+        }
+    };
+}
+
+fn main() {
+    let x = foo!({ 3 });
+}
diff --git a/src/test/ui/parser/issue-87812.stderr b/src/test/ui/parser/issue-87812.stderr
new file mode 100644
index 00000000000..d61ee23a50b
--- /dev/null
+++ b/src/test/ui/parser/issue-87812.stderr
@@ -0,0 +1,22 @@
+error: this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression
+  --> $DIR/issue-87812.rs:6:13
+   |
+LL |             break '_l $f;
+   |             ^^^^^^^^^^^^
+...
+LL |     let x = foo!({ 3 });
+   |             ----------- in this macro invocation
+   |
+note: the lint level is defined here
+  --> $DIR/issue-87812.rs:1:9
+   |
+LL | #![deny(break_with_label_and_loop)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: this error originates in the macro `foo` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: wrap this expression in parentheses
+   |
+LL |             break '_l ($f);
+   |                       +  +
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed b/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed
new file mode 100644
index 00000000000..76f661baed7
--- /dev/null
+++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.fixed
@@ -0,0 +1,27 @@
+// See https://github.com/rust-lang/rust/issues/88475
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(array_into_iter)]
+#![allow(unused)]
+
+struct FooIter;
+
+trait MyIntoIter {
+    fn into_iter(self) -> FooIter;
+}
+
+impl<T, const N: usize> MyIntoIter for [T; N] {
+    fn into_iter(self) -> FooIter {
+        FooIter
+    }
+}
+
+struct Point;
+
+pub fn main() {
+    let points: [Point; 1] = [Point];
+    let y = MyIntoIter::into_iter(points);
+    //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021
+    //~| WARNING this changes meaning in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.rs b/src/test/ui/rust-2021/array-into-iter-ambiguous.rs
new file mode 100644
index 00000000000..83fbf8f6c21
--- /dev/null
+++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.rs
@@ -0,0 +1,27 @@
+// See https://github.com/rust-lang/rust/issues/88475
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(array_into_iter)]
+#![allow(unused)]
+
+struct FooIter;
+
+trait MyIntoIter {
+    fn into_iter(self) -> FooIter;
+}
+
+impl<T, const N: usize> MyIntoIter for [T; N] {
+    fn into_iter(self) -> FooIter {
+        FooIter
+    }
+}
+
+struct Point;
+
+pub fn main() {
+    let points: [Point; 1] = [Point];
+    let y = points.into_iter();
+    //~^ WARNING trait method `into_iter` will become ambiguous in Rust 2021
+    //~| WARNING this changes meaning in Rust 2021
+}
diff --git a/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
new file mode 100644
index 00000000000..fac8d21c7b4
--- /dev/null
+++ b/src/test/ui/rust-2021/array-into-iter-ambiguous.stderr
@@ -0,0 +1,16 @@
+warning: trait method `into_iter` will become ambiguous in Rust 2021
+  --> $DIR/array-into-iter-ambiguous.rs:24:13
+   |
+LL |     let y = points.into_iter();
+   |             ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `MyIntoIter::into_iter(points)`
+   |
+note: the lint level is defined here
+  --> $DIR/array-into-iter-ambiguous.rs:5:9
+   |
+LL | #![warn(array_into_iter)]
+   |         ^^^^^^^^^^^^^^^
+   = warning: this changes meaning in Rust 2021
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/IntoIterator-for-arrays.html>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed
new file mode 100644
index 00000000000..a1b6f5b16ba
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.fixed
@@ -0,0 +1,30 @@
+// See https://github.com/rust-lang/rust/issues/88470
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+pub trait PyTryFrom<'v, T>: Sized {
+    fn try_from<V>(value: V) -> Result<&'v Self, T>;
+}
+
+pub trait PyTryInto<T>: Sized {
+    fn try_into(&self) -> Result<&T, i32>;
+}
+
+struct Foo;
+
+impl<U> PyTryInto<U> for Foo
+where
+    U: for<'v> PyTryFrom<'v, i32>,
+{
+    fn try_into(&self) -> Result<&U, i32> {
+        <U as PyTryFrom<'_, _>>::try_from(self)
+        //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+        //~| this is accepted in the current edition (Rust 2018)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs
new file mode 100644
index 00000000000..142ba552002
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.rs
@@ -0,0 +1,30 @@
+// See https://github.com/rust-lang/rust/issues/88470
+// run-rustfix
+// edition:2018
+// check-pass
+#![warn(rust_2021_prelude_collisions)]
+#![allow(dead_code)]
+#![allow(unused_imports)]
+
+pub trait PyTryFrom<'v, T>: Sized {
+    fn try_from<V>(value: V) -> Result<&'v Self, T>;
+}
+
+pub trait PyTryInto<T>: Sized {
+    fn try_into(&self) -> Result<&T, i32>;
+}
+
+struct Foo;
+
+impl<U> PyTryInto<U> for Foo
+where
+    U: for<'v> PyTryFrom<'v, i32>,
+{
+    fn try_into(&self) -> Result<&U, i32> {
+        U::try_from(self)
+        //~^ WARNING trait-associated function `try_from` will become ambiguous in Rust 2021
+        //~| this is accepted in the current edition (Rust 2018)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr
new file mode 100644
index 00000000000..14ad9b017b6
--- /dev/null
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic-trait.stderr
@@ -0,0 +1,16 @@
+warning: trait-associated function `try_from` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-generic-trait.rs:24:9
+   |
+LL |         U::try_from(self)
+   |         ^^^^^^^^^^^ help: disambiguate the associated function: `<U as PyTryFrom<'_, _>>::try_from`
+   |
+note: the lint level is defined here
+  --> $DIR/future-prelude-collision-generic-trait.rs:5:9
+   |
+LL | #![warn(rust_2021_prelude_collisions)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: 1 warning emitted
+
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
index f0d8cb944cf..1bb9ba37774 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.fixed
@@ -6,32 +6,32 @@
 #![allow(dead_code)]
 #![allow(unused_imports)]
 
-struct Generic<T, U>(T, U);
+struct Generic<'a, U>(&'a U);
 
 trait MyFromIter {
     fn from_iter(_: i32) -> Self;
 }
 
-impl MyFromIter for Generic<i32, i32> {
-    fn from_iter(x: i32) -> Self {
-        Self(x, x)
+impl MyFromIter for Generic<'static, i32> {
+    fn from_iter(_: i32) -> Self {
+        todo!()
     }
 }
 
-impl std::iter::FromIterator<i32> for Generic<i32, i32> {
+impl std::iter::FromIterator<i32> for Generic<'static, i32> {
     fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
         todo!()
     }
 }
 
 fn main() {
-    <Generic<_, _> as MyFromIter>::from_iter(1);
+    <Generic<'_, _> as MyFromIter>::from_iter(1);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
     //~| this is accepted in the current edition (Rust 2018)
-    <Generic::<i32, i32> as MyFromIter>::from_iter(1);
+    <Generic::<'static, i32> as MyFromIter>::from_iter(1);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
     //~| this is accepted in the current edition (Rust 2018)
-    <Generic::<_, _> as MyFromIter>::from_iter(1);
+    <Generic::<'_, _> as MyFromIter>::from_iter(1);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
     //~| this is accepted in the current edition (Rust 2018)
 }
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.rs b/src/test/ui/rust-2021/future-prelude-collision-generic.rs
index 19840537059..d7f8affc61a 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-generic.rs
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.rs
@@ -6,19 +6,19 @@
 #![allow(dead_code)]
 #![allow(unused_imports)]
 
-struct Generic<T, U>(T, U);
+struct Generic<'a, U>(&'a U);
 
 trait MyFromIter {
     fn from_iter(_: i32) -> Self;
 }
 
-impl MyFromIter for Generic<i32, i32> {
-    fn from_iter(x: i32) -> Self {
-        Self(x, x)
+impl MyFromIter for Generic<'static, i32> {
+    fn from_iter(_: i32) -> Self {
+        todo!()
     }
 }
 
-impl std::iter::FromIterator<i32> for Generic<i32, i32> {
+impl std::iter::FromIterator<i32> for Generic<'static, i32> {
     fn from_iter<T: IntoIterator<Item = i32>>(_: T) -> Self {
         todo!()
     }
@@ -28,10 +28,10 @@ fn main() {
     Generic::from_iter(1);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
     //~| this is accepted in the current edition (Rust 2018)
-    Generic::<i32, i32>::from_iter(1);
+    Generic::<'static, i32>::from_iter(1);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
     //~| this is accepted in the current edition (Rust 2018)
-    Generic::<_, _>::from_iter(1);
+    Generic::<'_, _>::from_iter(1);
     //~^ WARNING trait-associated function `from_iter` will become ambiguous in Rust 2021
     //~| this is accepted in the current edition (Rust 2018)
 }
diff --git a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
index 0a722baa185..e1d3f3c0a46 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-generic.stderr
@@ -2,7 +2,7 @@ warning: trait-associated function `from_iter` will become ambiguous in Rust 202
   --> $DIR/future-prelude-collision-generic.rs:28:5
    |
 LL |     Generic::from_iter(1);
-   |     ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<_, _> as MyFromIter>::from_iter`
+   |     ^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic<'_, _> as MyFromIter>::from_iter`
    |
 note: the lint level is defined here
   --> $DIR/future-prelude-collision-generic.rs:5:9
@@ -15,8 +15,8 @@ LL | #![warn(rust_2021_prelude_collisions)]
 warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
   --> $DIR/future-prelude-collision-generic.rs:31:5
    |
-LL |     Generic::<i32, i32>::from_iter(1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<i32, i32> as MyFromIter>::from_iter`
+LL |     Generic::<'static, i32>::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<'static, i32> as MyFromIter>::from_iter`
    |
    = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
@@ -24,8 +24,8 @@ LL |     Generic::<i32, i32>::from_iter(1);
 warning: trait-associated function `from_iter` will become ambiguous in Rust 2021
   --> $DIR/future-prelude-collision-generic.rs:34:5
    |
-LL |     Generic::<_, _>::from_iter(1);
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<_, _> as MyFromIter>::from_iter`
+LL |     Generic::<'_, _>::from_iter(1);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: disambiguate the associated function: `<Generic::<'_, _> as MyFromIter>::from_iter`
    |
    = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
index c5ff0b4bcd0..15ccff7496e 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.fixed
@@ -56,4 +56,15 @@ mod c {
     }
 }
 
+mod d {
+    use super::m::*;
+
+    fn main() {
+        // See https://github.com/rust-lang/rust/issues/88471
+        let _: u32 = TryIntoU32::try_into(3u8).unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this is accepted in the current edition
+    }
+}
+
 fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.rs b/src/test/ui/rust-2021/future-prelude-collision-imported.rs
index cd39eec47f2..cdffcaf7545 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-imported.rs
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.rs
@@ -56,4 +56,15 @@ mod c {
     }
 }
 
+mod d {
+    use super::m::*;
+
+    fn main() {
+        // See https://github.com/rust-lang/rust/issues/88471
+        let _: u32 = 3u8.try_into().unwrap();
+        //~^ WARNING trait method `try_into` will become ambiguous in Rust 2021
+        //~^^ WARNING this is accepted in the current edition
+    }
+}
+
 fn main() {}
diff --git a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
index fbda5d61f36..56abb8abd4d 100644
--- a/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
+++ b/src/test/ui/rust-2021/future-prelude-collision-imported.stderr
@@ -30,5 +30,14 @@ LL |         let _: u32 = 3u8.try_into().unwrap();
    = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
    = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
 
-warning: 3 warnings emitted
+warning: trait method `try_into` will become ambiguous in Rust 2021
+  --> $DIR/future-prelude-collision-imported.rs:64:22
+   |
+LL |         let _: u32 = 3u8.try_into().unwrap();
+   |                      ^^^^^^^^^^^^^^ help: disambiguate the associated function: `TryIntoU32::try_into(3u8)`
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/prelude.html>
+
+warning: 4 warnings emitted
 
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs
new file mode 100644
index 00000000000..a1584581e6c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+mod m {
+    type Foo = impl std::fmt::Debug;
+
+    pub fn foo() -> Foo {
+        22_u32
+    }
+}
+
+fn is_send<T: Send>(_: T) {}
+
+fn main() {
+    is_send(m::foo());
+}
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs
new file mode 100644
index 00000000000..745379efa6d
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+mod m {
+    use std::rc::Rc;
+
+    type Foo = impl std::fmt::Debug;
+
+    pub fn foo() -> Foo {
+        Rc::new(22_u32)
+    }
+}
+
+fn is_send<T: Send>(_: T) {}
+
+fn main() {
+    is_send(m::foo());
+    //~^ ERROR: `Rc<u32>` cannot be sent between threads safely [E0277]
+}
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
new file mode 100644
index 00000000000..d60be4b1ccf
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage2.stderr
@@ -0,0 +1,20 @@
+error[E0277]: `Rc<u32>` cannot be sent between threads safely
+  --> $DIR/auto-trait-leakage2.rs:17:5
+   |
+LL |     type Foo = impl std::fmt::Debug;
+   |                -------------------- within this `impl Debug`
+...
+LL |     is_send(m::foo());
+   |     ^^^^^^^ `Rc<u32>` cannot be sent between threads safely
+   |
+   = help: within `impl Debug`, the trait `Send` is not implemented for `Rc<u32>`
+   = note: required because it appears within the type `impl Debug`
+note: required by a bound in `is_send`
+  --> $DIR/auto-trait-leakage2.rs:14:15
+   |
+LL | fn is_send<T: Send>(_: T) {}
+   |               ^^^^ required by this bound in `is_send`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs
new file mode 100644
index 00000000000..5fb7a9473d3
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.rs
@@ -0,0 +1,21 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+// FIXME This should compile, but it currently doesn't
+
+mod m {
+    type Foo = impl std::fmt::Debug;
+    //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391]
+
+    pub fn foo() -> Foo {
+        22_u32
+    }
+
+    pub fn bar() {
+        is_send(foo());
+    }
+
+    fn is_send<T: Send>(_: T) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
new file mode 100644
index 00000000000..ac7bbd272c7
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/auto-trait-leakage3.stderr
@@ -0,0 +1,22 @@
+error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
+  --> $DIR/auto-trait-leakage3.rs:7:16
+   |
+LL |     type Foo = impl std::fmt::Debug;
+   |                ^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires type-checking `m::bar`...
+  --> $DIR/auto-trait-leakage3.rs:14:5
+   |
+LL |     pub fn bar() {
+   |     ^^^^^^^^^^^^
+   = note: ...which requires evaluating trait selection obligation `impl std::fmt::Debug: std::marker::Send`...
+   = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in module `m`
+  --> $DIR/auto-trait-leakage3.rs:6:1
+   |
+LL | mod m {
+   | ^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.rs b/src/test/ui/type-alias-impl-trait/inference-cycle.rs
new file mode 100644
index 00000000000..c781e200bf8
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/inference-cycle.rs
@@ -0,0 +1,26 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+mod m {
+    type Foo = impl std::fmt::Debug;
+    //~^ ERROR: cycle detected when computing type of `m::Foo::{opaque#0}` [E0391]
+
+    // Cycle: error today, but it'd be nice if it eventually worked
+
+    pub fn foo() -> Foo {
+        is_send(bar())
+    }
+
+    pub fn bar() {
+        is_send(foo()); // Today: error
+    }
+
+    fn baz() {
+        let f: Foo = 22_u32;
+        //~^ ERROR: mismatched types [E0308]
+    }
+
+    fn is_send<T: Send>(_: T) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/inference-cycle.stderr b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr
new file mode 100644
index 00000000000..ac0ca8e048c
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/inference-cycle.stderr
@@ -0,0 +1,37 @@
+error[E0391]: cycle detected when computing type of `m::Foo::{opaque#0}`
+  --> $DIR/inference-cycle.rs:5:16
+   |
+LL |     type Foo = impl std::fmt::Debug;
+   |                ^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires type-checking `m::bar`...
+  --> $DIR/inference-cycle.rs:14:5
+   |
+LL |     pub fn bar() {
+   |     ^^^^^^^^^^^^
+   = note: ...which requires evaluating trait selection obligation `impl std::fmt::Debug: std::marker::Send`...
+   = note: ...which again requires computing type of `m::Foo::{opaque#0}`, completing the cycle
+note: cycle used when checking item types in module `m`
+  --> $DIR/inference-cycle.rs:4:1
+   |
+LL | mod m {
+   | ^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/inference-cycle.rs:19:22
+   |
+LL |     type Foo = impl std::fmt::Debug;
+   |                -------------------- the expected opaque type
+...
+LL |         let f: Foo = 22_u32;
+   |                ---   ^^^^^^ expected opaque type, found `u32`
+   |                |
+   |                expected due to this
+   |
+   = note: expected opaque type `impl Debug`
+                     found type `u32`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0391.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs
new file mode 100644
index 00000000000..efb88dabf34
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference.rs
@@ -0,0 +1,18 @@
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::fmt::Debug;
+
+type FooX = impl Debug;
+
+trait Foo<A> { }
+
+impl Foo<()> for () { }
+
+fn foo() -> impl Foo<FooX> {
+    ()
+}
+
+fn main() { }
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs
new file mode 100644
index 00000000000..9b26a652978
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.rs
@@ -0,0 +1,19 @@
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::fmt::Debug;
+
+type FooX = impl Debug;
+//~^ ERROR: could not find defining uses
+
+trait Foo<A> {}
+
+impl Foo<()> for () {}
+impl Foo<u32> for () {}
+
+fn foo() -> impl Foo<FooX> {
+    //~^ ERROR: the trait bound `(): Foo<impl Debug>` is not satisfied [E0277]
+    ()
+}
+
+fn main() {}
diff --git a/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
new file mode 100644
index 00000000000..7e24ee644b1
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/nested-tait-inference2.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `(): Foo<impl Debug>` is not satisfied
+  --> $DIR/nested-tait-inference2.rs:14:13
+   |
+LL | fn foo() -> impl Foo<FooX> {
+   |             ^^^^^^^^^^^^^^ the trait `Foo<impl Debug>` is not implemented for `()`
+   |
+   = help: the following implementations were found:
+             <() as Foo<()>>
+             <() as Foo<u32>>
+
+error: could not find defining uses
+  --> $DIR/nested-tait-inference2.rs:6:13
+   |
+LL | type FooX = impl Debug;
+   |             ^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/type-alias-impl-trait/weird-return-types.rs b/src/test/ui/type-alias-impl-trait/weird-return-types.rs
new file mode 100644
index 00000000000..faad5ee956a
--- /dev/null
+++ b/src/test/ui/type-alias-impl-trait/weird-return-types.rs
@@ -0,0 +1,16 @@
+// edition:2018
+// check-pass
+
+#![feature(type_alias_impl_trait)]
+#![allow(dead_code)]
+
+use std::future::Future;
+use std::fmt::Debug;
+
+type Foo = impl Debug;
+
+fn f() -> impl Future<Output = Foo> {
+    async move { 22_u32 }
+}
+
+fn main() {}