about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-01-17 23:01:35 +0000
committerbors <bors@rust-lang.org>2022-01-17 23:01:35 +0000
commit86b1581ea0e0e47196e1ea70b2d980b3eee72623 (patch)
tree8a54ed3035f97f62f60564089a2ba1bfecc32f0b
parentee5d8d37baaf5b5a81a98396952839c73ae41c68 (diff)
parent68d47def017ff062270fd553bb4c7f8fbcc672c0 (diff)
downloadrust-86b1581ea0e0e47196e1ea70b2d980b3eee72623.tar.gz
rust-86b1581ea0e0e47196e1ea70b2d980b3eee72623.zip
Auto merge of #93009 - matthiaskrgr:rollup-3fkxg6i, r=matthiaskrgr
Rollup of 10 pull requests

Successful merges:

 - #90498 (Clarifications in the target tier policy)
 - #92164 (Implement `#[rustc_must_implement_one_of]` attribute)
 - #92729 (rustc_codegen_llvm: Remove (almost) unused span parameter from many functions in metadata.rs)
 - #92752 (Correct minor typos in some long error code explanations)
 - #92801 (Enable wrapping words by default)
 - #92825 (Rename environment variable for overriding rustc version)
 - #92877 (Remove LLVMRustMarkAllFunctionsNounwind)
 - #92936 (rustdoc: Remove `collect` in `html::markdown::parse`)
 - #92956 (Add `log2` and `log10` to `NonZeroU*`)
 - #92960 (Use `carrying_{mul|add}` in `num::bignum`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs162
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs19
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0038.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0183.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0521.md2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0581.md2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
-rw-r--r--compiler/rustc_incremental/src/persist/file_format.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp19
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs8
-rw-r--r--compiler/rustc_span/src/def_id.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_typeck/src/check/check.rs29
-rw-r--r--compiler/rustc_typeck/src/check/mod.rs25
-rw-r--r--compiler/rustc_typeck/src/collect.rs106
-rw-r--r--library/core/src/num/bignum.rs42
-rw-r--r--library/core/src/num/int_log10.rs247
-rw-r--r--library/core/src/num/int_macros.rs6
-rw-r--r--library/core/src/num/mod.rs16
-rw-r--r--library/core/src/num/nonzero.rs52
-rw-r--r--library/core/src/num/uint_macros.rs17
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support/TEMPLATE.md52
-rw-r--r--src/doc/rustc/src/target-tier-policy.md43
-rw-r--r--src/librustdoc/html/markdown.rs4
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css16
-rw-r--r--src/test/incremental/cache_file_headers.rs2
-rw-r--r--src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile2
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of.rs44
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of.stderr15
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs19
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr34
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.rs13
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.stderr11
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs38
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr82
42 files changed, 793 insertions, 382 deletions
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index ddba43cd1f1..6afa649b6de 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -349,13 +349,6 @@ fn fat_lto(
             );
             save_temp_bitcode(cgcx, &module, "lto.after-restriction");
         }
-
-        if cgcx.no_landing_pads {
-            unsafe {
-                llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
-            }
-            save_temp_bitcode(cgcx, &module, "lto.after-nounwind");
-        }
     }
 
     Ok(LtoModuleCodegen::Fat { module: Some(module), _serialized_bitcode: serialized_bitcode })
@@ -770,16 +763,6 @@ pub unsafe fn optimize_thin_module(
             return Err(write::llvm_err(&diag_handler, msg));
         }
 
-        // Like with "fat" LTO, get some better optimizations if landing pads
-        // are disabled by removing all landing pads.
-        if cgcx.no_landing_pads {
-            let _timer = cgcx
-                .prof
-                .generic_activity_with_arg("LLVM_thin_lto_remove_landing_pads", thin_module.name());
-            llvm::LLVMRustMarkAllFunctionsNounwind(llmod);
-            save_temp_bitcode(cgcx, &module, "thin-lto-after-nounwind");
-        }
-
         // Up next comes the per-module local analyses that we do for Thin LTO.
         // Each of these functions is basically copied from the LLVM
         // implementation and then tailored to suit this implementation. Ideally
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 5c02e3d0fa7..3d5fd2f354e 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -27,18 +27,18 @@ use rustc_fs_util::path_to_c_string;
 use rustc_hir::def::CtorKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_index::vec::{Idx, IndexVec};
+use rustc_middle::bug;
 use rustc_middle::mir::{self, GeneratorLayout};
 use rustc_middle::ty::layout::{self, IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout};
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{
     self, AdtKind, GeneratorSubsts, Instance, ParamEnv, Ty, TyCtxt, COMMON_VTABLE_ENTRIES,
 };
-use rustc_middle::{bug, span_bug};
 use rustc_query_system::ich::NodeIdHashingMode;
 use rustc_session::config::{self, DebugInfo};
 use rustc_span::symbol::Symbol;
 use rustc_span::FileNameDisplayPreference;
-use rustc_span::{self, SourceFile, SourceFileHash, Span};
+use rustc_span::{self, SourceFile, SourceFileHash};
 use rustc_target::abi::{Abi, Align, HasDataLayout, Integer, TagEncoding};
 use rustc_target::abi::{Int, Pointer, F32, F64};
 use rustc_target::abi::{Primitive, Size, VariantIdx, Variants};
@@ -381,9 +381,8 @@ fn fixed_vec_metadata<'ll, 'tcx>(
     unique_type_id: UniqueTypeId,
     array_or_slice_type: Ty<'tcx>,
     element_type: Ty<'tcx>,
-    span: Span,
 ) -> MetadataCreationResult<'ll> {
-    let element_type_metadata = type_metadata(cx, element_type, span);
+    let element_type_metadata = type_metadata(cx, element_type);
 
     return_if_metadata_created_in_meantime!(cx, unique_type_id);
 
@@ -416,11 +415,10 @@ fn vec_slice_metadata<'ll, 'tcx>(
     slice_ptr_type: Ty<'tcx>,
     element_type: Ty<'tcx>,
     unique_type_id: UniqueTypeId,
-    span: Span,
 ) -> MetadataCreationResult<'ll> {
     let data_ptr_type = cx.tcx.mk_imm_ptr(element_type);
 
-    let data_ptr_metadata = type_metadata(cx, data_ptr_type, span);
+    let data_ptr_metadata = type_metadata(cx, data_ptr_type);
 
     return_if_metadata_created_in_meantime!(cx, unique_type_id);
 
@@ -442,7 +440,7 @@ fn vec_slice_metadata<'ll, 'tcx>(
         },
         MemberDescription {
             name: "length".to_owned(),
-            type_metadata: type_metadata(cx, cx.tcx.types.usize, span),
+            type_metadata: type_metadata(cx, cx.tcx.types.usize),
             offset: pointer_size,
             size: usize_size,
             align: usize_align,
@@ -452,8 +450,6 @@ fn vec_slice_metadata<'ll, 'tcx>(
         },
     ];
 
-    let file_metadata = unknown_file_metadata(cx);
-
     let metadata = composite_type_metadata(
         cx,
         slice_ptr_type,
@@ -461,8 +457,6 @@ fn vec_slice_metadata<'ll, 'tcx>(
         unique_type_id,
         member_descriptions,
         NO_SCOPE_METADATA,
-        file_metadata,
-        span,
     );
     MetadataCreationResult::new(metadata, false)
 }
@@ -471,7 +465,6 @@ fn subroutine_type_metadata<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     unique_type_id: UniqueTypeId,
     signature: ty::PolyFnSig<'tcx>,
-    span: Span,
 ) -> MetadataCreationResult<'ll> {
     let signature =
         cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), signature);
@@ -480,12 +473,12 @@ fn subroutine_type_metadata<'ll, 'tcx>(
         // return type
         match signature.output().kind() {
             ty::Tuple(tys) if tys.is_empty() => None,
-            _ => Some(type_metadata(cx, signature.output(), span)),
+            _ => Some(type_metadata(cx, signature.output())),
         },
     )
     .chain(
         // regular arguments
-        signature.inputs().iter().map(|argument_type| Some(type_metadata(cx, argument_type, span))),
+        signature.inputs().iter().map(|argument_type| Some(type_metadata(cx, argument_type))),
     )
     .collect();
 
@@ -541,8 +534,6 @@ fn trait_pointer_metadata<'ll, 'tcx>(
         None => (NO_SCOPE_METADATA, compute_debuginfo_type_name(cx.tcx, trait_type, true)),
     };
 
-    let file_metadata = unknown_file_metadata(cx);
-
     let layout = cx.layout_of(cx.tcx.mk_mut_ptr(trait_type));
 
     assert_eq!(abi::FAT_PTR_ADDR, 0);
@@ -553,11 +544,7 @@ fn trait_pointer_metadata<'ll, 'tcx>(
     let member_descriptions = vec![
         MemberDescription {
             name: "pointer".to_owned(),
-            type_metadata: type_metadata(
-                cx,
-                cx.tcx.mk_mut_ptr(cx.tcx.types.u8),
-                rustc_span::DUMMY_SP,
-            ),
+            type_metadata: type_metadata(cx, cx.tcx.mk_mut_ptr(cx.tcx.types.u8)),
             offset: layout.fields.offset(0),
             size: data_ptr_field.size,
             align: data_ptr_field.align.abi,
@@ -567,7 +554,7 @@ fn trait_pointer_metadata<'ll, 'tcx>(
         },
         MemberDescription {
             name: "vtable".to_owned(),
-            type_metadata: type_metadata(cx, vtable_field.ty, rustc_span::DUMMY_SP),
+            type_metadata: type_metadata(cx, vtable_field.ty),
             offset: layout.fields.offset(1),
             size: vtable_field.size,
             align: vtable_field.align.abi,
@@ -584,16 +571,10 @@ fn trait_pointer_metadata<'ll, 'tcx>(
         unique_type_id,
         member_descriptions,
         containing_scope,
-        file_metadata,
-        rustc_span::DUMMY_SP,
     )
 }
 
-pub fn type_metadata<'ll, 'tcx>(
-    cx: &CodegenCx<'ll, 'tcx>,
-    t: Ty<'tcx>,
-    usage_site_span: Span,
-) -> &'ll DIType {
+pub fn type_metadata<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll DIType {
     // Get the unique type ID of this type.
     let unique_type_id = {
         let mut type_map = debug_context(cx).type_map.borrow_mut();
@@ -630,14 +611,14 @@ pub fn type_metadata<'ll, 'tcx>(
     debug!("type_metadata: {:?}", t);
 
     let ptr_metadata = |ty: Ty<'tcx>| match *ty.kind() {
-        ty::Slice(typ) => Ok(vec_slice_metadata(cx, t, typ, unique_type_id, usage_site_span)),
-        ty::Str => Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id, usage_site_span)),
+        ty::Slice(typ) => Ok(vec_slice_metadata(cx, t, typ, unique_type_id)),
+        ty::Str => Ok(vec_slice_metadata(cx, t, cx.tcx.types.u8, unique_type_id)),
         ty::Dynamic(..) => Ok(MetadataCreationResult::new(
             trait_pointer_metadata(cx, ty, Some(t), unique_type_id),
             false,
         )),
         _ => {
-            let pointee_metadata = type_metadata(cx, ty, usage_site_span);
+            let pointee_metadata = type_metadata(cx, ty);
 
             if let Some(metadata) =
                 debug_context(cx).type_map.borrow().find_metadata_for_unique_id(unique_type_id)
@@ -656,10 +637,8 @@ pub fn type_metadata<'ll, 'tcx>(
         ty::Tuple(elements) if elements.is_empty() => {
             MetadataCreationResult::new(basic_type_metadata(cx, t), false)
         }
-        ty::Array(typ, _) | ty::Slice(typ) => {
-            fixed_vec_metadata(cx, unique_type_id, t, typ, usage_site_span)
-        }
-        ty::Str => fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8, usage_site_span),
+        ty::Array(typ, _) | ty::Slice(typ) => fixed_vec_metadata(cx, unique_type_id, t, typ),
+        ty::Str => fixed_vec_metadata(cx, unique_type_id, t, cx.tcx.types.i8),
         ty::Dynamic(..) => {
             MetadataCreationResult::new(trait_pointer_metadata(cx, t, None, unique_type_id), false)
         }
@@ -710,8 +689,7 @@ pub fn type_metadata<'ll, 'tcx>(
             type_map.borrow_mut().register_type_with_metadata(t, temp_type);
 
             let fn_metadata =
-                subroutine_type_metadata(cx, unique_type_id, t.fn_sig(cx.tcx), usage_site_span)
-                    .metadata;
+                subroutine_type_metadata(cx, unique_type_id, t.fn_sig(cx.tcx)).metadata;
 
             type_map.borrow_mut().remove_type(t);
 
@@ -721,15 +699,8 @@ pub fn type_metadata<'ll, 'tcx>(
         ty::Closure(def_id, substs) => {
             let upvar_tys: Vec<_> = substs.as_closure().upvar_tys().collect();
             let containing_scope = get_namespace_for_item(cx, def_id);
-            prepare_tuple_metadata(
-                cx,
-                t,
-                &upvar_tys,
-                unique_type_id,
-                usage_site_span,
-                Some(containing_scope),
-            )
-            .finalize(cx)
+            prepare_tuple_metadata(cx, t, &upvar_tys, unique_type_id, Some(containing_scope))
+                .finalize(cx)
         }
         ty::Generator(def_id, substs, _) => {
             let upvar_tys: Vec<_> = substs
@@ -737,25 +708,18 @@ pub fn type_metadata<'ll, 'tcx>(
                 .prefix_tys()
                 .map(|t| cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), t))
                 .collect();
-            prepare_enum_metadata(cx, t, def_id, unique_type_id, usage_site_span, upvar_tys)
-                .finalize(cx)
+            prepare_enum_metadata(cx, t, def_id, unique_type_id, upvar_tys).finalize(cx)
         }
         ty::Adt(def, ..) => match def.adt_kind() {
-            AdtKind::Struct => {
-                prepare_struct_metadata(cx, t, unique_type_id, usage_site_span).finalize(cx)
-            }
-            AdtKind::Union => {
-                prepare_union_metadata(cx, t, unique_type_id, usage_site_span).finalize(cx)
-            }
+            AdtKind::Struct => prepare_struct_metadata(cx, t, unique_type_id).finalize(cx),
+            AdtKind::Union => prepare_union_metadata(cx, t, unique_type_id).finalize(cx),
             AdtKind::Enum => {
-                prepare_enum_metadata(cx, t, def.did, unique_type_id, usage_site_span, vec![])
-                    .finalize(cx)
+                prepare_enum_metadata(cx, t, def.did, unique_type_id, vec![]).finalize(cx)
             }
         },
         ty::Tuple(elements) => {
             let tys: Vec<_> = elements.iter().map(|k| k.expect_ty()).collect();
-            prepare_tuple_metadata(cx, t, &tys, unique_type_id, usage_site_span, NO_SCOPE_METADATA)
-                .finalize(cx)
+            prepare_tuple_metadata(cx, t, &tys, unique_type_id, NO_SCOPE_METADATA).finalize(cx)
         }
         // Type parameters from polymorphized functions.
         ty::Param(_) => MetadataCreationResult::new(param_type_metadata(cx, t), false),
@@ -770,8 +734,7 @@ pub fn type_metadata<'ll, 'tcx>(
             let metadata_for_uid = match type_map.find_metadata_for_unique_id(unique_type_id) {
                 Some(metadata) => metadata,
                 None => {
-                    span_bug!(
-                        usage_site_span,
+                    bug!(
                         "expected type metadata for unique \
                                type ID '{}' to already be in \
                                the `debuginfo::TypeMap` but it \
@@ -785,8 +748,7 @@ pub fn type_metadata<'ll, 'tcx>(
             match type_map.find_metadata_for_type(t) {
                 Some(metadata) => {
                     if metadata != metadata_for_uid {
-                        span_bug!(
-                            usage_site_span,
+                        bug!(
                             "mismatch between `Ty` and \
                                    `UniqueTypeId` maps in \
                                    `debuginfo::TypeMap`. \
@@ -1283,7 +1245,6 @@ impl<'ll, 'tcx> MemberDescriptionFactory<'ll, 'tcx> {
 struct StructMemberDescriptionFactory<'tcx> {
     ty: Ty<'tcx>,
     variant: &'tcx ty::VariantDef,
-    span: Span,
 }
 
 impl<'tcx> StructMemberDescriptionFactory<'tcx> {
@@ -1305,7 +1266,7 @@ impl<'tcx> StructMemberDescriptionFactory<'tcx> {
                 let field = layout.field(cx, i);
                 MemberDescription {
                     name,
-                    type_metadata: type_metadata(cx, field.ty, self.span),
+                    type_metadata: type_metadata(cx, field.ty),
                     offset: layout.fields.offset(i),
                     size: field.size,
                     align: field.align.abi,
@@ -1322,7 +1283,6 @@ fn prepare_struct_metadata<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     struct_type: Ty<'tcx>,
     unique_type_id: UniqueTypeId,
-    span: Span,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let struct_name = compute_debuginfo_type_name(cx.tcx, struct_type, false);
 
@@ -1348,7 +1308,7 @@ fn prepare_struct_metadata<'ll, 'tcx>(
         unique_type_id,
         struct_metadata_stub,
         struct_metadata_stub,
-        StructMDF(StructMemberDescriptionFactory { ty: struct_type, variant, span }),
+        StructMDF(StructMemberDescriptionFactory { ty: struct_type, variant }),
     )
 }
 
@@ -1385,7 +1345,6 @@ fn closure_saved_names_of_captured_variables(tcx: TyCtxt<'_>, def_id: DefId) ->
 struct TupleMemberDescriptionFactory<'tcx> {
     ty: Ty<'tcx>,
     component_types: Vec<Ty<'tcx>>,
-    span: Span,
 }
 
 impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
@@ -1412,7 +1371,7 @@ impl<'tcx> TupleMemberDescriptionFactory<'tcx> {
                 };
                 MemberDescription {
                     name,
-                    type_metadata: type_metadata(cx, component_type, self.span),
+                    type_metadata: type_metadata(cx, component_type),
                     offset: layout.fields.offset(i),
                     size,
                     align,
@@ -1430,7 +1389,6 @@ fn prepare_tuple_metadata<'ll, 'tcx>(
     tuple_type: Ty<'tcx>,
     component_types: &[Ty<'tcx>],
     unique_type_id: UniqueTypeId,
-    span: Span,
     containing_scope: Option<&'ll DIScope>,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let tuple_name = compute_debuginfo_type_name(cx.tcx, tuple_type, false);
@@ -1453,7 +1411,6 @@ fn prepare_tuple_metadata<'ll, 'tcx>(
         TupleMDF(TupleMemberDescriptionFactory {
             ty: tuple_type,
             component_types: component_types.to_vec(),
-            span,
         }),
     )
 }
@@ -1465,7 +1422,6 @@ fn prepare_tuple_metadata<'ll, 'tcx>(
 struct UnionMemberDescriptionFactory<'tcx> {
     layout: TyAndLayout<'tcx>,
     variant: &'tcx ty::VariantDef,
-    span: Span,
 }
 
 impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
@@ -1481,7 +1437,7 @@ impl<'tcx> UnionMemberDescriptionFactory<'tcx> {
                 let field = self.layout.field(cx, i);
                 MemberDescription {
                     name: f.name.to_string(),
-                    type_metadata: type_metadata(cx, field.ty, self.span),
+                    type_metadata: type_metadata(cx, field.ty),
                     offset: Size::ZERO,
                     size: field.size,
                     align: field.align.abi,
@@ -1498,7 +1454,6 @@ fn prepare_union_metadata<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     union_type: Ty<'tcx>,
     unique_type_id: UniqueTypeId,
-    span: Span,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let union_name = compute_debuginfo_type_name(cx.tcx, union_type, false);
 
@@ -1518,7 +1473,7 @@ fn prepare_union_metadata<'ll, 'tcx>(
         unique_type_id,
         union_metadata_stub,
         union_metadata_stub,
-        UnionMDF(UnionMemberDescriptionFactory { layout: cx.layout_of(union_type), variant, span }),
+        UnionMDF(UnionMemberDescriptionFactory { layout: cx.layout_of(union_type), variant }),
     )
 }
 
@@ -1573,7 +1528,6 @@ struct EnumMemberDescriptionFactory<'ll, 'tcx> {
     layout: TyAndLayout<'tcx>,
     tag_type_metadata: Option<&'ll DIType>,
     common_members: Vec<Option<&'ll DIType>>,
-    span: Span,
 }
 
 impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
@@ -1605,7 +1559,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
         // msvc, then we need to use a different, fallback encoding of the debuginfo.
         let fallback = cpp_like_debuginfo(cx.tcx);
         // This will always find the metadata in the type map.
-        let self_metadata = type_metadata(cx, self.enum_type, self.span);
+        let self_metadata = type_metadata(cx, self.enum_type);
 
         match self.layout.variants {
             Variants::Single { index } => {
@@ -1617,7 +1571,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
 
                 let variant_info = variant_info_for(index);
                 let (variant_type_metadata, member_description_factory) =
-                    describe_enum_variant(cx, self.layout, variant_info, self_metadata, self.span);
+                    describe_enum_variant(cx, self.layout, variant_info, self_metadata);
 
                 let member_descriptions = member_description_factory.create_member_descriptions(cx);
 
@@ -1682,13 +1636,8 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                     .map(|(i, _)| {
                         let variant = self.layout.for_variant(cx, i);
                         let variant_info = variant_info_for(i);
-                        let (variant_type_metadata, member_desc_factory) = describe_enum_variant(
-                            cx,
-                            variant,
-                            variant_info,
-                            self_metadata,
-                            self.span,
-                        );
+                        let (variant_type_metadata, member_desc_factory) =
+                            describe_enum_variant(cx, variant, variant_info, self_metadata);
 
                         let member_descriptions =
                             member_desc_factory.create_member_descriptions(cx);
@@ -1807,7 +1756,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                             tag.value.size(cx).bits(),
                             tag.value.align(cx).abi.bits() as u32,
                             create_DIArray(DIB(cx), &tags),
-                            type_metadata(cx, discr_enum_ty, self.span),
+                            type_metadata(cx, discr_enum_ty),
                             true,
                         )
                     };
@@ -1818,7 +1767,6 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                         dataful_variant_layout,
                         variant_info,
                         self_metadata,
-                        self.span,
                     );
 
                     let member_descriptions = member_desc_factory.create_member_descriptions(cx);
@@ -1864,13 +1812,7 @@ impl<'ll, 'tcx> EnumMemberDescriptionFactory<'ll, 'tcx> {
                             let variant = self.layout.for_variant(cx, i);
                             let variant_info = variant_info_for(i);
                             let (variant_type_metadata, member_desc_factory) =
-                                describe_enum_variant(
-                                    cx,
-                                    variant,
-                                    variant_info,
-                                    self_metadata,
-                                    self.span,
-                                );
+                                describe_enum_variant(cx, variant, variant_info, self_metadata);
 
                             let member_descriptions =
                                 member_desc_factory.create_member_descriptions(cx);
@@ -1908,7 +1850,6 @@ struct VariantMemberDescriptionFactory<'tcx> {
     /// Cloned from the `layout::Struct` describing the variant.
     offsets: Vec<Size>,
     args: Vec<(String, Ty<'tcx>)>,
-    span: Span,
 }
 
 impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
@@ -1923,7 +1864,7 @@ impl<'tcx> VariantMemberDescriptionFactory<'tcx> {
                 let (size, align) = cx.size_and_align_of(ty);
                 MemberDescription {
                     name: name.to_string(),
-                    type_metadata: type_metadata(cx, ty, self.span),
+                    type_metadata: type_metadata(cx, ty),
                     offset: self.offsets[i],
                     size,
                     align,
@@ -2011,7 +1952,6 @@ fn describe_enum_variant<'ll, 'tcx>(
     layout: layout::TyAndLayout<'tcx>,
     variant: VariantInfo<'_, 'tcx>,
     containing_scope: &'ll DIScope,
-    span: Span,
 ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) {
     let metadata_stub = variant.map_struct_name(|variant_name| {
         let unique_type_id = debug_context(cx)
@@ -2033,8 +1973,7 @@ fn describe_enum_variant<'ll, 'tcx>(
         .map(|i| (variant.field_name(i), layout.field(cx, i).ty))
         .collect();
 
-    let member_description_factory =
-        VariantMDF(VariantMemberDescriptionFactory { offsets, args, span });
+    let member_description_factory = VariantMDF(VariantMemberDescriptionFactory { offsets, args });
 
     (metadata_stub, member_description_factory)
 }
@@ -2044,7 +1983,6 @@ fn prepare_enum_metadata<'ll, 'tcx>(
     enum_type: Ty<'tcx>,
     enum_def_id: DefId,
     unique_type_id: UniqueTypeId,
-    span: Span,
     outer_field_tys: Vec<Ty<'tcx>>,
 ) -> RecursiveTypeDescription<'ll, 'tcx> {
     let tcx = cx.tcx;
@@ -2109,8 +2047,7 @@ fn prepare_enum_metadata<'ll, 'tcx>(
             Some(discriminant_type_metadata) => discriminant_type_metadata,
             None => {
                 let (discriminant_size, discriminant_align) = (discr.size(cx), discr.align(cx));
-                let discriminant_base_type_metadata =
-                    type_metadata(cx, discr.to_ty(tcx), rustc_span::DUMMY_SP);
+                let discriminant_base_type_metadata = type_metadata(cx, discr.to_ty(tcx));
 
                 let item_name;
                 let discriminant_name = match enum_type.kind() {
@@ -2202,7 +2139,6 @@ fn prepare_enum_metadata<'ll, 'tcx>(
                 layout,
                 tag_type_metadata: discriminant_type_metadata,
                 common_members: vec![],
-                span,
             }),
         );
     }
@@ -2272,11 +2208,8 @@ fn prepare_enum_metadata<'ll, 'tcx>(
     let outer_fields = match layout.variants {
         Variants::Single { .. } => vec![],
         Variants::Multiple { .. } => {
-            let tuple_mdf = TupleMemberDescriptionFactory {
-                ty: enum_type,
-                component_types: outer_field_tys,
-                span,
-            };
+            let tuple_mdf =
+                TupleMemberDescriptionFactory { ty: enum_type, component_types: outer_field_tys };
             tuple_mdf
                 .create_member_descriptions(cx)
                 .into_iter()
@@ -2352,7 +2285,6 @@ fn prepare_enum_metadata<'ll, 'tcx>(
             layout,
             tag_type_metadata: None,
             common_members: outer_fields,
-            span,
         }),
     )
 }
@@ -2368,11 +2300,6 @@ fn composite_type_metadata<'ll, 'tcx>(
     composite_type_unique_id: UniqueTypeId,
     member_descriptions: Vec<MemberDescription<'ll>>,
     containing_scope: Option<&'ll DIScope>,
-
-    // Ignore source location information as long as it
-    // can't be reconstructed for non-local crates.
-    _file_metadata: &'ll DIFile,
-    _definition_span: Span,
 ) -> &'ll DICompositeType {
     // Create the (empty) struct metadata node ...
     let composite_type_metadata = create_struct_stub(
@@ -2450,8 +2377,7 @@ fn compute_type_parameters<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -
                     if let GenericArgKind::Type(ty) = kind.unpack() {
                         let actual_type =
                             cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
-                        let actual_type_metadata =
-                            type_metadata(cx, actual_type, rustc_span::DUMMY_SP);
+                        let actual_type_metadata = type_metadata(cx, actual_type);
                         let name = name.as_str();
                         Some(unsafe {
                             Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
@@ -2593,7 +2519,7 @@ pub fn create_global_var_metadata<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId, g
 
     let is_local_to_unit = is_node_local_to_unit(cx, def_id);
     let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
-    let type_metadata = type_metadata(cx, variable_type, span);
+    let type_metadata = type_metadata(cx, variable_type);
     let var_name = tcx.item_name(def_id);
     let var_name = var_name.as_str();
     let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name;
@@ -2648,7 +2574,7 @@ fn vtable_type_metadata<'ll, 'tcx>(
     //        things simple instead of adding some ad-hoc disambiguation scheme.
     let vtable_type = tcx.mk_array(tcx.mk_imm_ptr(tcx.types.unit), vtable_entries.len() as u64);
 
-    type_metadata(cx, vtable_type, rustc_span::DUMMY_SP)
+    type_metadata(cx, vtable_type)
 }
 
 /// Creates debug information for the given vtable, which is for the
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index d1cea147a7a..61e49fab6ff 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -390,7 +390,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             signature.push(if fn_abi.ret.is_ignore() {
                 None
             } else {
-                Some(type_metadata(cx, fn_abi.ret.layout.ty, rustc_span::DUMMY_SP))
+                Some(type_metadata(cx, fn_abi.ret.layout.ty))
             });
 
             // Arguments types
@@ -415,15 +415,11 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         }
                         _ => t,
                     };
-                    Some(type_metadata(cx, t, rustc_span::DUMMY_SP))
+                    Some(type_metadata(cx, t))
                 }));
             } else {
-                signature.extend(
-                    fn_abi
-                        .args
-                        .iter()
-                        .map(|arg| Some(type_metadata(cx, arg.layout.ty, rustc_span::DUMMY_SP))),
-                );
+                signature
+                    .extend(fn_abi.args.iter().map(|arg| Some(type_metadata(cx, arg.layout.ty))));
             }
 
             create_DIArray(DIB(cx), &signature[..])
@@ -453,8 +449,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                         if let GenericArgKind::Type(ty) = kind.unpack() {
                             let actual_type =
                                 cx.tcx.normalize_erasing_regions(ParamEnv::reveal_all(), ty);
-                            let actual_type_metadata =
-                                type_metadata(cx, actual_type, rustc_span::DUMMY_SP);
+                            let actual_type_metadata = type_metadata(cx, actual_type);
                             let name = name.as_str();
                             Some(unsafe {
                                 Some(llvm::LLVMRustDIBuilderCreateTemplateTypeParameter(
@@ -509,7 +504,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
                             if cx.sess().opts.debuginfo == DebugInfo::Full
                                 && !impl_self_ty.needs_subst()
                             {
-                                Some(type_metadata(cx, impl_self_ty, rustc_span::DUMMY_SP))
+                                Some(type_metadata(cx, impl_self_ty))
                             } else {
                                 Some(namespace::item_namespace(cx, def.did))
                             }
@@ -584,7 +579,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         let loc = self.lookup_debug_loc(span.lo());
         let file_metadata = file_metadata(self, &loc.file);
 
-        let type_metadata = type_metadata(self, variable_type, span);
+        let type_metadata = type_metadata(self, variable_type);
 
         let (argument_index, dwarf_tag) = match variable_kind {
             ArgumentVariable(index) => (index as c_uint, DW_TAG_arg_variable),
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index bc8d7b3e9e2..a1c7d2b4f61 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2320,7 +2320,6 @@ extern "C" {
     pub fn LLVMRustSetNormalizedTarget(M: &Module, triple: *const c_char);
     pub fn LLVMRustAddAlwaysInlinePass(P: &PassManagerBuilder, AddLifetimes: bool);
     pub fn LLVMRustRunRestrictionPass(M: &Module, syms: *const *const c_char, len: size_t);
-    pub fn LLVMRustMarkAllFunctionsNounwind(M: &Module);
 
     pub fn LLVMRustOpenArchive(path: *const c_char) -> Option<&'static mut Archive>;
     pub fn LLVMRustArchiveIteratorNew(AR: &Archive) -> &mut ArchiveIterator<'_>;
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index bea454458c4..540979ce02d 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -32,7 +32,7 @@ use rustc_session::Session;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::sym;
 use rustc_span::{BytePos, FileName, InnerSpan, Pos, Span};
-use rustc_target::spec::{MergeFunctions, PanicStrategy, SanitizerSet};
+use rustc_target::spec::{MergeFunctions, SanitizerSet};
 
 use std::any::Any;
 use std::fs;
@@ -313,7 +313,6 @@ pub struct CodegenContext<B: WriteBackendMethods> {
     pub backend: B,
     pub prof: SelfProfilerRef,
     pub lto: Lto,
-    pub no_landing_pads: bool,
     pub save_temps: bool,
     pub fewer_names: bool,
     pub time_trace: bool,
@@ -1039,7 +1038,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
         crate_types: sess.crate_types().to_vec(),
         each_linked_rlib_for_lto,
         lto: sess.lto(),
-        no_landing_pads: sess.panic_strategy() == PanicStrategy::Abort,
         fewer_names: sess.fewer_names(),
         save_temps: sess.opts.cg.save_temps,
         time_trace: sess.opts.debugging_opts.llvm_time_trace,
diff --git a/compiler/rustc_error_codes/src/error_codes/E0038.md b/compiler/rustc_error_codes/src/error_codes/E0038.md
index ca2eaa54057..584b78554ef 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0038.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0038.md
@@ -15,7 +15,7 @@ Two general aspects of trait object types give rise to the restrictions:
      these types can only be accessed through pointers, such as `&dyn Trait` or
      `Box<dyn Trait>`. The size of such a pointer is known, but the size of the
      `dyn Trait` object pointed-to by the pointer is _opaque_ to code working
-     with it, and different tait objects with the same trait object type may
+     with it, and different trait objects with the same trait object type may
      have different sizes.
 
   2. The pointer used to access a trait object is paired with an extra pointer
@@ -167,7 +167,7 @@ implementation on-demand. If you call `foo()` with a `bool` parameter, the
 compiler will only generate code for `foo::<bool>()`. When we have additional
 type parameters, the number of monomorphized implementations the compiler
 generates does not grow drastically, since the compiler will only generate an
-implementation if the function is called with unparametrized substitutions
+implementation if the function is called with unparameterized substitutions
 (i.e., substitutions where none of the substituted types are themselves
 parameterized).
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0183.md b/compiler/rustc_error_codes/src/error_codes/E0183.md
index 7e1d08daae1..92fa4c7c21e 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0183.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0183.md
@@ -1,4 +1,4 @@
-Manual implemetation of a `Fn*` trait.
+Manual implementation of a `Fn*` trait.
 
 Erroneous code example:
 
@@ -33,7 +33,7 @@ impl FnOnce<()> for MyClosure {  // ok!
 }
 ```
 
-The argumements must be a tuple representing the argument list.
+The arguments must be a tuple representing the argument list.
 For more info, see the [tracking issue][iss29625]:
 
 [iss29625]: https://github.com/rust-lang/rust/issues/29625
diff --git a/compiler/rustc_error_codes/src/error_codes/E0521.md b/compiler/rustc_error_codes/src/error_codes/E0521.md
index 65dcac983ac..fedf6365fb5 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0521.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0521.md
@@ -10,7 +10,7 @@ let _add = |el: &str| {
 };
 ```
 
-A type anotation of a closure parameter implies a new lifetime declaration.
+A type annotation of a closure parameter implies a new lifetime declaration.
 Consider to drop it, the compiler is reliably able to infer them.
 
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0581.md b/compiler/rustc_error_codes/src/error_codes/E0581.md
index 89f6e3269ec..02468dd9466 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0581.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0581.md
@@ -10,7 +10,7 @@ fn main() {
 }
 ```
 
-The problem here is that the lifetime isn't contrained by any of the arguments,
+The problem here is that the lifetime isn't constrained by any of the arguments,
 making it impossible to determine how long it's supposed to live.
 
 To fix this issue, either use the lifetime in the arguments, or use the
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 46817bc9c3f..5309f217b4a 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -682,6 +682,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         "the `#[rustc_skip_array_during_method_dispatch]` attribute is used to exclude a trait \
         from method dispatch when the receiver is an array, for compatibility in editions < 2021."
     ),
+    rustc_attr!(
+        rustc_must_implement_one_of, Normal, template!(List: "function1, function2, ..."), ErrorFollowing,
+        "the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete \
+        definition of a trait, it's currently in experimental form and should be changed before \
+        being exposed outside of the std"
+    ),
 
     // ==========================================================================
     // Internal attributes, Testing:
diff --git a/compiler/rustc_incremental/src/persist/file_format.rs b/compiler/rustc_incremental/src/persist/file_format.rs
index 392c5bdc15a..68180a2214a 100644
--- a/compiler/rustc_incremental/src/persist/file_format.rs
+++ b/compiler/rustc_incremental/src/persist/file_format.rs
@@ -190,7 +190,7 @@ fn report_format_mismatch(report_incremental_info: bool, file: &Path, message: &
 
 fn rustc_version(nightly_build: bool) -> String {
     if nightly_build {
-        if let Some(val) = env::var_os("RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER") {
+        if let Some(val) = env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
             return val.to_string_lossy().into_owned();
         }
     }
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index f06fc3edf58..7030fd53704 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -1168,25 +1168,6 @@ extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
   passes.run(*unwrap(M));
 }
 
-extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
-  for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
-       ++GV) {
-    GV->setDoesNotThrow();
-    Function *F = dyn_cast<Function>(GV);
-    if (F == nullptr)
-      continue;
-
-    for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
-      for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
-        if (isa<InvokeInst>(I)) {
-          InvokeInst *CI = cast<InvokeInst>(I);
-          CI->setDoesNotThrow();
-        }
-      }
-    }
-  }
-}
-
 extern "C" void
 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
                                        LLVMTargetMachineRef TMR) {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 39aa1844d69..220bc9c5f75 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -820,6 +820,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                     data.skip_array_during_method_dispatch,
                     data.specialization_kind,
                     self.def_path_hash(item_id),
+                    data.must_implement_one_of,
                 )
             }
             EntryKind::TraitAlias => ty::TraitDef::new(
@@ -831,6 +832,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
                 false,
                 ty::trait_def::TraitSpecializationKind::None,
                 self.def_path_hash(item_id),
+                None,
             ),
             _ => bug!("def-index does not refer to trait or trait alias"),
         }
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index ee6656ce372..ebb78adf343 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1513,6 +1513,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     is_marker: trait_def.is_marker,
                     skip_array_during_method_dispatch: trait_def.skip_array_during_method_dispatch,
                     specialization_kind: trait_def.specialization_kind,
+                    must_implement_one_of: trait_def.must_implement_one_of.clone(),
                 };
 
                 EntryKind::Trait(self.lazy(data))
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 75c5880f05d..8424a31d59f 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -378,6 +378,7 @@ struct TraitData {
     is_marker: bool,
     skip_array_during_method_dispatch: bool,
     specialization_kind: ty::trait_def::TraitSpecializationKind,
+    must_implement_one_of: Option<Box<[Ident]>>,
 }
 
 #[derive(TyEncodable, TyDecodable)]
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index 34d059f4ec8..9f8053d4a4e 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -1,7 +1,7 @@
 use crate::traits::specialization_graph;
 use crate::ty::fast_reject::{self, SimplifiedType, SimplifyParams, StripReferences};
 use crate::ty::fold::TypeFoldable;
-use crate::ty::{Ty, TyCtxt};
+use crate::ty::{Ident, Ty, TyCtxt};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::definitions::DefPathHash;
@@ -44,6 +44,10 @@ pub struct TraitDef {
     /// The ICH of this trait's DefPath, cached here so it doesn't have to be
     /// recomputed all the time.
     pub def_path_hash: DefPathHash,
+
+    /// List of functions from `#[rustc_must_implement_one_of]` attribute one of which
+    /// must be implemented.
+    pub must_implement_one_of: Option<Box<[Ident]>>,
 }
 
 /// Whether this trait is treated specially by the standard library
@@ -87,6 +91,7 @@ impl<'tcx> TraitDef {
         skip_array_during_method_dispatch: bool,
         specialization_kind: TraitSpecializationKind,
         def_path_hash: DefPathHash,
+        must_implement_one_of: Option<Box<[Ident]>>,
     ) -> TraitDef {
         TraitDef {
             def_id,
@@ -97,6 +102,7 @@ impl<'tcx> TraitDef {
             skip_array_during_method_dispatch,
             specialization_kind,
             def_path_hash,
+            must_implement_one_of,
         }
     }
 
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 0bba918994c..5390eed89fa 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -176,9 +176,9 @@ impl StableCrateId {
         // and no -Cmetadata, symbols from the same crate compiled with different versions of
         // rustc are named the same.
         //
-        // RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER is used to inject rustc version information
+        // RUSTC_FORCE_RUSTC_VERSION is used to inject rustc version information
         // during testing.
-        if let Some(val) = std::env::var_os("RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER") {
+        if let Some(val) = std::env::var_os("RUSTC_FORCE_RUSTC_VERSION") {
             hasher.write(val.to_string_lossy().into_owned().as_bytes())
         } else {
             hasher.write(option_env!("CFG_VERSION").unwrap_or("unknown version").as_bytes());
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 8020893e166..21f4312de35 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1162,6 +1162,7 @@ symbols! {
         rustc_macro_transparency,
         rustc_main,
         rustc_mir,
+        rustc_must_implement_one_of,
         rustc_nonnull_optimization_guaranteed,
         rustc_object_lifetime_default,
         rustc_on_unimplemented,
diff --git a/compiler/rustc_typeck/src/check/check.rs b/compiler/rustc_typeck/src/check/check.rs
index 7a3d5990329..eb49cc0233d 100644
--- a/compiler/rustc_typeck/src/check/check.rs
+++ b/compiler/rustc_typeck/src/check/check.rs
@@ -978,6 +978,10 @@ fn check_impl_items_against_trait<'tcx>(
     if let Ok(ancestors) = trait_def.ancestors(tcx, impl_id.to_def_id()) {
         // Check for missing items from trait
         let mut missing_items = Vec::new();
+
+        let mut must_implement_one_of: Option<&[Ident]> =
+            trait_def.must_implement_one_of.as_deref();
+
         for &trait_item_id in tcx.associated_item_def_ids(impl_trait_ref.def_id) {
             let is_implemented = ancestors
                 .leaf_def(tcx, trait_item_id)
@@ -986,12 +990,37 @@ fn check_impl_items_against_trait<'tcx>(
             if !is_implemented && tcx.impl_defaultness(impl_id).is_final() {
                 missing_items.push(tcx.associated_item(trait_item_id));
             }
+
+            if let Some(required_items) = &must_implement_one_of {
+                // true if this item is specifically implemented in this impl
+                let is_implemented_here = ancestors
+                    .leaf_def(tcx, trait_item_id)
+                    .map_or(false, |node_item| !node_item.defining_node.is_from_trait());
+
+                if is_implemented_here {
+                    let trait_item = tcx.associated_item(trait_item_id);
+                    if required_items.contains(&trait_item.ident) {
+                        must_implement_one_of = None;
+                    }
+                }
+            }
         }
 
         if !missing_items.is_empty() {
             let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
             missing_items_err(tcx, impl_span, &missing_items, full_impl_span);
         }
+
+        if let Some(missing_items) = must_implement_one_of {
+            let impl_span = tcx.sess.source_map().guess_head_span(full_impl_span);
+            let attr_span = tcx
+                .get_attrs(impl_trait_ref.def_id)
+                .iter()
+                .find(|attr| attr.has_name(sym::rustc_must_implement_one_of))
+                .map(|attr| attr.span);
+
+            missing_items_must_implement_one_of_err(tcx, impl_span, missing_items, attr_span);
+        }
     }
 }
 
diff --git a/compiler/rustc_typeck/src/check/mod.rs b/compiler/rustc_typeck/src/check/mod.rs
index 719266ad5a4..059d4a7f3a4 100644
--- a/compiler/rustc_typeck/src/check/mod.rs
+++ b/compiler/rustc_typeck/src/check/mod.rs
@@ -637,6 +637,31 @@ fn missing_items_err(
     err.emit();
 }
 
+fn missing_items_must_implement_one_of_err(
+    tcx: TyCtxt<'_>,
+    impl_span: Span,
+    missing_items: &[Ident],
+    annotation_span: Option<Span>,
+) {
+    let missing_items_msg =
+        missing_items.iter().map(Ident::to_string).collect::<Vec<_>>().join("`, `");
+
+    let mut err = struct_span_err!(
+        tcx.sess,
+        impl_span,
+        E0046,
+        "not all trait items implemented, missing one of: `{}`",
+        missing_items_msg
+    );
+    err.span_label(impl_span, format!("missing one of `{}` in implementation", missing_items_msg));
+
+    if let Some(annotation_span) = annotation_span {
+        err.span_note(annotation_span, "required because of this annotation");
+    }
+
+    err.emit();
+}
+
 /// Resugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
 fn bounds_from_generic_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 2ed98e20f1d..314174e0f85 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1190,9 +1190,11 @@ fn super_predicates_that_define_assoc_type(
 fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
     let item = tcx.hir().expect_item(def_id.expect_local());
 
-    let (is_auto, unsafety) = match item.kind {
-        hir::ItemKind::Trait(is_auto, unsafety, ..) => (is_auto == hir::IsAuto::Yes, unsafety),
-        hir::ItemKind::TraitAlias(..) => (false, hir::Unsafety::Normal),
+    let (is_auto, unsafety, items) = match item.kind {
+        hir::ItemKind::Trait(is_auto, unsafety, .., items) => {
+            (is_auto == hir::IsAuto::Yes, unsafety, items)
+        }
+        hir::ItemKind::TraitAlias(..) => (false, hir::Unsafety::Normal, &[][..]),
         _ => span_bug!(item.span, "trait_def_of_item invoked on non-trait"),
     };
 
@@ -1219,6 +1221,103 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
         ty::trait_def::TraitSpecializationKind::None
     };
     let def_path_hash = tcx.def_path_hash(def_id);
+
+    let must_implement_one_of = tcx
+        .get_attrs(def_id)
+        .iter()
+        .find(|attr| attr.has_name(sym::rustc_must_implement_one_of))
+        // Check that there are at least 2 arguments of `#[rustc_must_implement_one_of]`
+        // and that they are all identifiers
+        .and_then(|attr| match attr.meta_item_list() {
+            Some(items) if items.len() < 2 => {
+                tcx.sess
+                    .struct_span_err(
+                        attr.span,
+                        "the `#[rustc_must_implement_one_of]` attribute must be \
+                        used with at least 2 args",
+                    )
+                    .emit();
+
+                None
+            }
+            Some(items) => items
+                .into_iter()
+                .map(|item| item.ident().ok_or(item.span()))
+                .collect::<Result<Box<[_]>, _>>()
+                .map_err(|span| {
+                    tcx.sess
+                        .struct_span_err(span, "must be a name of an associated function")
+                        .emit();
+                })
+                .ok()
+                .zip(Some(attr.span)),
+            // Error is reported by `rustc_attr!`
+            None => None,
+        })
+        // Check that all arguments of `#[rustc_must_implement_one_of]` reference
+        // functions in the trait with default implementations
+        .and_then(|(list, attr_span)| {
+            let errors = list.iter().filter_map(|ident| {
+                let item = items.iter().find(|item| item.ident == *ident);
+
+                match item {
+                    Some(item) if matches!(item.kind, hir::AssocItemKind::Fn { .. }) => {
+                        if !item.defaultness.has_value() {
+                            tcx.sess
+                                .struct_span_err(
+                                    item.span,
+                                    "This function doesn't have a default implementation",
+                                )
+                                .span_note(attr_span, "required by this annotation")
+                                .emit();
+
+                            return Some(());
+                        }
+
+                        return None;
+                    }
+                    Some(item) => tcx
+                        .sess
+                        .struct_span_err(item.span, "Not a function")
+                        .span_note(attr_span, "required by this annotation")
+                        .note(
+                            "All `#[rustc_must_implement_one_of]` arguments \
+                            must be associated function names",
+                        )
+                        .emit(),
+                    None => tcx
+                        .sess
+                        .struct_span_err(ident.span, "Function not found in this trait")
+                        .emit(),
+                }
+
+                Some(())
+            });
+
+            (errors.count() == 0).then_some(list)
+        })
+        // Check for duplicates
+        .and_then(|list| {
+            let mut set: FxHashMap<Symbol, Span> = FxHashMap::default();
+            let mut no_dups = true;
+
+            for ident in &*list {
+                if let Some(dup) = set.insert(ident.name, ident.span) {
+                    tcx.sess
+                        .struct_span_err(vec![dup, ident.span], "Functions names are duplicated")
+                        .note(
+                            "All `#[rustc_must_implement_one_of]` arguments \
+                            must be unique",
+                        )
+                        .emit();
+
+                    no_dups = false;
+                }
+            }
+
+            no_dups.then_some(list)
+        });
+
     ty::TraitDef::new(
         def_id,
         unsafety,
@@ -1228,6 +1327,7 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
         skip_array_during_method_dispatch,
         spec_kind,
         def_path_hash,
+        must_implement_one_of,
     )
 }
 
diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs
index 98d8a8a1d74..de85fdd6ed2 100644
--- a/library/core/src/num/bignum.rs
+++ b/library/core/src/num/bignum.rs
@@ -19,18 +19,8 @@
 )]
 #![macro_use]
 
-use crate::intrinsics;
-
 /// Arithmetic operations required by bignums.
 pub trait FullOps: Sized {
-    /// Returns `(carry', v')` such that `carry' * 2^W + v' = self + other + carry`,
-    /// where `W` is the number of bits in `Self`.
-    fn full_add(self, other: Self, carry: bool) -> (bool /* carry */, Self);
-
-    /// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + carry`,
-    /// where `W` is the number of bits in `Self`.
-    fn full_mul(self, other: Self, carry: Self) -> (Self /* carry */, Self);
-
     /// Returns `(carry', v')` such that `carry' * 2^W + v' = self * other + other2 + carry`,
     /// where `W` is the number of bits in `Self`.
     fn full_mul_add(self, other: Self, other2: Self, carry: Self) -> (Self /* carry */, Self);
@@ -45,22 +35,6 @@ macro_rules! impl_full_ops {
     ($($ty:ty: add($addfn:path), mul/div($bigty:ident);)*) => (
         $(
             impl FullOps for $ty {
-                fn full_add(self, other: $ty, carry: bool) -> (bool, $ty) {
-                    // This cannot overflow; the output is between `0` and `2 * 2^nbits - 1`.
-                    // FIXME: will LLVM optimize this into ADC or similar?
-                    let (v, carry1) = intrinsics::add_with_overflow(self, other);
-                    let (v, carry2) = intrinsics::add_with_overflow(v, if carry {1} else {0});
-                    (carry1 || carry2, v)
-                }
-
-                fn full_mul(self, other: $ty, carry: $ty) -> ($ty, $ty) {
-                    // This cannot overflow;
-                    // the output is between `0` and `2^nbits * (2^nbits - 1)`.
-                    // FIXME: will LLVM optimize this into ADC or similar?
-                    let v = (self as $bigty) * (other as $bigty) + (carry as $bigty);
-                    ((v >> <$ty>::BITS) as $ty, v as $ty)
-                }
-
                 fn full_mul_add(self, other: $ty, other2: $ty, carry: $ty) -> ($ty, $ty) {
                     // This cannot overflow;
                     // the output is between `0` and `2^nbits * (2^nbits - 1)`.
@@ -173,12 +147,11 @@ macro_rules! define_bignum {
             pub fn add<'a>(&'a mut self, other: &$name) -> &'a mut $name {
                 use crate::cmp;
                 use crate::iter;
-                use crate::num::bignum::FullOps;
 
                 let mut sz = cmp::max(self.size, other.size);
                 let mut carry = false;
                 for (a, b) in iter::zip(&mut self.base[..sz], &other.base[..sz]) {
-                    let (c, v) = (*a).full_add(*b, carry);
+                    let (v, c) = (*a).carrying_add(*b, carry);
                     *a = v;
                     carry = c;
                 }
@@ -191,13 +164,11 @@ macro_rules! define_bignum {
             }
 
             pub fn add_small(&mut self, other: $ty) -> &mut $name {
-                use crate::num::bignum::FullOps;
-
-                let (mut carry, v) = self.base[0].full_add(other, false);
+                let (v, mut carry) = self.base[0].carrying_add(other, false);
                 self.base[0] = v;
                 let mut i = 1;
                 while carry {
-                    let (c, v) = self.base[i].full_add(0, carry);
+                    let (v, c) = self.base[i].carrying_add(0, carry);
                     self.base[i] = v;
                     carry = c;
                     i += 1;
@@ -212,12 +183,11 @@ macro_rules! define_bignum {
             pub fn sub<'a>(&'a mut self, other: &$name) -> &'a mut $name {
                 use crate::cmp;
                 use crate::iter;
-                use crate::num::bignum::FullOps;
 
                 let sz = cmp::max(self.size, other.size);
                 let mut noborrow = true;
                 for (a, b) in iter::zip(&mut self.base[..sz], &other.base[..sz]) {
-                    let (c, v) = (*a).full_add(!*b, noborrow);
+                    let (v, c) = (*a).carrying_add(!*b, noborrow);
                     *a = v;
                     noborrow = c;
                 }
@@ -229,12 +199,10 @@ macro_rules! define_bignum {
             /// Multiplies itself by a digit-sized `other` and returns its own
             /// mutable reference.
             pub fn mul_small(&mut self, other: $ty) -> &mut $name {
-                use crate::num::bignum::FullOps;
-
                 let mut sz = self.size;
                 let mut carry = 0;
                 for a in &mut self.base[..sz] {
-                    let (c, v) = (*a).full_mul(other, carry);
+                    let (v, c) = (*a).carrying_mul(other, carry);
                     *a = v;
                     carry = c;
                 }
diff --git a/library/core/src/num/int_log10.rs b/library/core/src/num/int_log10.rs
index a8455fb355b..cc26c04a5d4 100644
--- a/library/core/src/num/int_log10.rs
+++ b/library/core/src/num/int_log10.rs
@@ -1,141 +1,140 @@
-mod unchecked {
-    // 0 < val <= u8::MAX
-    #[inline]
-    pub const fn u8(val: u8) -> u32 {
-        let val = val as u32;
-
-        // For better performance, avoid branches by assembling the solution
-        // in the bits above the low 8 bits.
-
-        // Adding c1 to val gives 10 in the top bits for val < 10, 11 for val >= 10
-        const C1: u32 = 0b11_00000000 - 10; // 758
-        // Adding c2 to val gives 01 in the top bits for val < 100, 10 for val >= 100
-        const C2: u32 = 0b10_00000000 - 100; // 412
-
-        // Value of top bits:
-        //            +c1  +c2  1&2
-        //     0..=9   10   01   00 = 0
-        //   10..=99   11   01   01 = 1
-        // 100..=255   11   10   10 = 2
-        ((val + C1) & (val + C2)) >> 8
-    }
+/// These functions compute the integer logarithm of their type, assuming
+/// that someone has already checked that the the value is strictly positive.
+
+// 0 < val <= u8::MAX
+#[inline]
+pub const fn u8(val: u8) -> u32 {
+    let val = val as u32;
+
+    // For better performance, avoid branches by assembling the solution
+    // in the bits above the low 8 bits.
+
+    // Adding c1 to val gives 10 in the top bits for val < 10, 11 for val >= 10
+    const C1: u32 = 0b11_00000000 - 10; // 758
+    // Adding c2 to val gives 01 in the top bits for val < 100, 10 for val >= 100
+    const C2: u32 = 0b10_00000000 - 100; // 412
+
+    // Value of top bits:
+    //            +c1  +c2  1&2
+    //     0..=9   10   01   00 = 0
+    //   10..=99   11   01   01 = 1
+    // 100..=255   11   10   10 = 2
+    ((val + C1) & (val + C2)) >> 8
+}
 
-    // 0 < val < 100_000
-    #[inline]
-    const fn less_than_5(val: u32) -> u32 {
-        // Similar to u8, when adding one of these constants to val,
-        // we get two possible bit patterns above the low 17 bits,
-        // depending on whether val is below or above the threshold.
-        const C1: u32 = 0b011_00000000000000000 - 10; // 393206
-        const C2: u32 = 0b100_00000000000000000 - 100; // 524188
-        const C3: u32 = 0b111_00000000000000000 - 1000; // 916504
-        const C4: u32 = 0b100_00000000000000000 - 10000; // 514288
-
-        // Value of top bits:
-        //                +c1  +c2  1&2  +c3  +c4  3&4   ^
-        //         0..=9  010  011  010  110  011  010  000 = 0
-        //       10..=99  011  011  011  110  011  010  001 = 1
-        //     100..=999  011  100  000  110  011  010  010 = 2
-        //   1000..=9999  011  100  000  111  011  011  011 = 3
-        // 10000..=99999  011  100  000  111  100  100  100 = 4
-        (((val + C1) & (val + C2)) ^ ((val + C3) & (val + C4))) >> 17
-    }
+// 0 < val < 100_000
+#[inline]
+const fn less_than_5(val: u32) -> u32 {
+    // Similar to u8, when adding one of these constants to val,
+    // we get two possible bit patterns above the low 17 bits,
+    // depending on whether val is below or above the threshold.
+    const C1: u32 = 0b011_00000000000000000 - 10; // 393206
+    const C2: u32 = 0b100_00000000000000000 - 100; // 524188
+    const C3: u32 = 0b111_00000000000000000 - 1000; // 916504
+    const C4: u32 = 0b100_00000000000000000 - 10000; // 514288
+
+    // Value of top bits:
+    //                +c1  +c2  1&2  +c3  +c4  3&4   ^
+    //         0..=9  010  011  010  110  011  010  000 = 0
+    //       10..=99  011  011  011  110  011  010  001 = 1
+    //     100..=999  011  100  000  110  011  010  010 = 2
+    //   1000..=9999  011  100  000  111  011  011  011 = 3
+    // 10000..=99999  011  100  000  111  100  100  100 = 4
+    (((val + C1) & (val + C2)) ^ ((val + C3) & (val + C4))) >> 17
+}
 
-    // 0 < val <= u16::MAX
-    #[inline]
-    pub const fn u16(val: u16) -> u32 {
-        less_than_5(val as u32)
-    }
+// 0 < val <= u16::MAX
+#[inline]
+pub const fn u16(val: u16) -> u32 {
+    less_than_5(val as u32)
+}
 
-    // 0 < val <= u32::MAX
-    #[inline]
-    pub const fn u32(mut val: u32) -> u32 {
-        let mut log = 0;
-        if val >= 100_000 {
-            val /= 100_000;
-            log += 5;
-        }
-        log + less_than_5(val)
+// 0 < val <= u32::MAX
+#[inline]
+pub const fn u32(mut val: u32) -> u32 {
+    let mut log = 0;
+    if val >= 100_000 {
+        val /= 100_000;
+        log += 5;
     }
+    log + less_than_5(val)
+}
 
-    // 0 < val <= u64::MAX
-    #[inline]
-    pub const fn u64(mut val: u64) -> u32 {
-        let mut log = 0;
-        if val >= 10_000_000_000 {
-            val /= 10_000_000_000;
-            log += 10;
-        }
-        if val >= 100_000 {
-            val /= 100_000;
-            log += 5;
-        }
-        log + less_than_5(val as u32)
+// 0 < val <= u64::MAX
+#[inline]
+pub const fn u64(mut val: u64) -> u32 {
+    let mut log = 0;
+    if val >= 10_000_000_000 {
+        val /= 10_000_000_000;
+        log += 10;
     }
-
-    // 0 < val <= u128::MAX
-    #[inline]
-    pub const fn u128(mut val: u128) -> u32 {
-        let mut log = 0;
-        if val >= 100_000_000_000_000_000_000_000_000_000_000 {
-            val /= 100_000_000_000_000_000_000_000_000_000_000;
-            log += 32;
-            return log + u32(val as u32);
-        }
-        if val >= 10_000_000_000_000_000 {
-            val /= 10_000_000_000_000_000;
-            log += 16;
-        }
-        log + u64(val as u64)
+    if val >= 100_000 {
+        val /= 100_000;
+        log += 5;
     }
+    log + less_than_5(val as u32)
+}
 
-    // 0 < val <= i8::MAX
-    #[inline]
-    pub const fn i8(val: i8) -> u32 {
-        u8(val as u8)
+// 0 < val <= u128::MAX
+#[inline]
+pub const fn u128(mut val: u128) -> u32 {
+    let mut log = 0;
+    if val >= 100_000_000_000_000_000_000_000_000_000_000 {
+        val /= 100_000_000_000_000_000_000_000_000_000_000;
+        log += 32;
+        return log + u32(val as u32);
     }
-
-    // 0 < val <= i16::MAX
-    #[inline]
-    pub const fn i16(val: i16) -> u32 {
-        u16(val as u16)
+    if val >= 10_000_000_000_000_000 {
+        val /= 10_000_000_000_000_000;
+        log += 16;
     }
+    log + u64(val as u64)
+}
 
-    // 0 < val <= i32::MAX
-    #[inline]
-    pub const fn i32(val: i32) -> u32 {
-        u32(val as u32)
-    }
+#[cfg(target_pointer_width = "16")]
+#[inline]
+pub const fn usize(val: usize) -> u32 {
+    u16(val as _)
+}
 
-    // 0 < val <= i64::MAX
-    #[inline]
-    pub const fn i64(val: i64) -> u32 {
-        u64(val as u64)
-    }
+#[cfg(target_pointer_width = "32")]
+#[inline]
+pub const fn usize(val: usize) -> u32 {
+    u32(val as _)
+}
 
-    // 0 < val <= i128::MAX
-    #[inline]
-    pub const fn i128(val: i128) -> u32 {
-        u128(val as u128)
-    }
+#[cfg(target_pointer_width = "64")]
+#[inline]
+pub const fn usize(val: usize) -> u32 {
+    u64(val as _)
+}
+
+// 0 < val <= i8::MAX
+#[inline]
+pub const fn i8(val: i8) -> u32 {
+    u8(val as u8)
 }
 
-macro_rules! impl_checked {
-    ($T:ident) => {
-        #[inline]
-        pub const fn $T(val: $T) -> Option<u32> {
-            if val > 0 { Some(unchecked::$T(val)) } else { None }
-        }
-    };
+// 0 < val <= i16::MAX
+#[inline]
+pub const fn i16(val: i16) -> u32 {
+    u16(val as u16)
 }
 
-impl_checked! { u8 }
-impl_checked! { u16 }
-impl_checked! { u32 }
-impl_checked! { u64 }
-impl_checked! { u128 }
-impl_checked! { i8 }
-impl_checked! { i16 }
-impl_checked! { i32 }
-impl_checked! { i64 }
-impl_checked! { i128 }
+// 0 < val <= i32::MAX
+#[inline]
+pub const fn i32(val: i32) -> u32 {
+    u32(val as u32)
+}
+
+// 0 < val <= i64::MAX
+#[inline]
+pub const fn i64(val: i64) -> u32 {
+    u64(val as u64)
+}
+
+// 0 < val <= i128::MAX
+#[inline]
+pub const fn i128(val: i128) -> u32 {
+    u128(val as u128)
+}
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 6f7c5a6d119..79436c8e8ed 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -2362,7 +2362,11 @@ macro_rules! int_impl {
                       without modifying the original"]
         #[inline]
         pub const fn checked_log10(self) -> Option<u32> {
-            int_log10::$ActualT(self as $ActualT)
+            if self > 0 {
+                Some(int_log10::$ActualT(self as $ActualT))
+            } else {
+                None
+            }
         }
 
         /// Computes the absolute value of `self`.
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index e3eab07b9df..721c030b410 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -264,7 +264,7 @@ const ASCII_CASE_MASK: u8 = 0b0010_0000;
 
 #[lang = "u8"]
 impl u8 {
-    uint_impl! { u8, u8, i8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
+    uint_impl! { u8, u8, i8, NonZeroU8, 8, 255, 2, "0x82", "0xa", "0x12", "0x12", "0x48", "[0x12]",
     "[0x12]", "", "" }
     widening_impl! { u8, u16, 8, unsigned }
 
@@ -813,21 +813,21 @@ impl u8 {
 
 #[lang = "u16"]
 impl u16 {
-    uint_impl! { u16, u16, i16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
+    uint_impl! { u16, u16, i16, NonZeroU16, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
     "[0x34, 0x12]", "[0x12, 0x34]", "", "" }
     widening_impl! { u16, u32, 16, unsigned }
 }
 
 #[lang = "u32"]
 impl u32 {
-    uint_impl! { u32, u32, i32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
+    uint_impl! { u32, u32, i32, NonZeroU32, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]", "", "" }
     widening_impl! { u32, u64, 32, unsigned }
 }
 
 #[lang = "u64"]
 impl u64 {
-    uint_impl! { u64, u64, i64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
+    uint_impl! { u64, u64, i64, NonZeroU64, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
@@ -837,7 +837,7 @@ impl u64 {
 
 #[lang = "u128"]
 impl u128 {
-    uint_impl! { u128, u128, i128, 128, 340282366920938463463374607431768211455, 16,
+    uint_impl! { u128, u128, i128, NonZeroU128, 128, 340282366920938463463374607431768211455, 16,
     "0x13f40000000000000000000000004f76", "0x4f7613f4", "0x12345678901234567890123456789012",
     "0x12907856341290785634129078563412", "0x48091e6a2c48091e6a2c48091e6a2c48",
     "[0x12, 0x90, 0x78, 0x56, 0x34, 0x12, 0x90, 0x78, \
@@ -850,7 +850,7 @@ impl u128 {
 #[cfg(target_pointer_width = "16")]
 #[lang = "usize"]
 impl usize {
-    uint_impl! { usize, u16, isize, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
+    uint_impl! { usize, u16, isize, NonZeroUsize, 16, 65535, 4, "0xa003", "0x3a", "0x1234", "0x3412", "0x2c48",
     "[0x34, 0x12]", "[0x12, 0x34]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
     widening_impl! { usize, u32, 16, unsigned }
@@ -858,7 +858,7 @@ impl usize {
 #[cfg(target_pointer_width = "32")]
 #[lang = "usize"]
 impl usize {
-    uint_impl! { usize, u32, isize, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
+    uint_impl! { usize, u32, isize, NonZeroUsize, 32, 4294967295, 8, "0x10000b3", "0xb301", "0x12345678",
     "0x78563412", "0x1e6a2c48", "[0x78, 0x56, 0x34, 0x12]", "[0x12, 0x34, 0x56, 0x78]",
     usize_isize_to_xe_bytes_doc!(), usize_isize_from_xe_bytes_doc!() }
     widening_impl! { usize, u64, 32, unsigned }
@@ -867,7 +867,7 @@ impl usize {
 #[cfg(target_pointer_width = "64")]
 #[lang = "usize"]
 impl usize {
-    uint_impl! { usize, u64, isize, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
+    uint_impl! { usize, u64, isize, NonZeroUsize, 64, 18446744073709551615, 12, "0xaa00000000006e1", "0x6e10aa",
     "0x1234567890123456", "0x5634129078563412", "0x6a2c48091e6a2c48",
     "[0x56, 0x34, 0x12, 0x90, 0x78, 0x56, 0x34, 0x12]",
     "[0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56]",
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 8f895c33a63..e21ae489179 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -302,7 +302,7 @@ nonzero_integers_div! {
 
 // A bunch of methods for unsigned nonzero types only.
 macro_rules! nonzero_unsigned_operations {
-    ( $( $Ty: ident($Int: ty); )+ ) => {
+    ( $( $Ty: ident($Int: ident); )+ ) => {
         $(
             impl $Ty {
                 /// Add an unsigned integer to a non-zero value.
@@ -442,6 +442,56 @@ macro_rules! nonzero_unsigned_operations {
                         None
                     }
                 }
+
+                /// Returns the base 2 logarithm of the number, rounded down.
+                ///
+                /// This is the same operation as
+                #[doc = concat!("[`", stringify!($Int), "::log2`],")]
+                /// except that it has no failure cases to worry about
+                /// since this value can never be zero.
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(int_log)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(7).unwrap().log2(), 2);")]
+                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(8).unwrap().log2(), 3);")]
+                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(9).unwrap().log2(), 3);")]
+                /// ```
+                #[unstable(feature = "int_log", issue = "70887")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
+                #[inline]
+                pub const fn log2(self) -> u32 {
+                    <$Int>::BITS - 1 - self.leading_zeros()
+                }
+
+                /// Returns the base 10 logarithm of the number, rounded down.
+                ///
+                /// This is the same operation as
+                #[doc = concat!("[`", stringify!($Int), "::log10`],")]
+                /// except that it has no failure cases to worry about
+                /// since this value can never be zero.
+                ///
+                /// # Examples
+                ///
+                /// ```
+                /// #![feature(int_log)]
+                #[doc = concat!("# use std::num::", stringify!($Ty), ";")]
+                ///
+                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(99).unwrap().log10(), 1);")]
+                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(100).unwrap().log10(), 2);")]
+                #[doc = concat!("assert_eq!(", stringify!($Ty), "::new(101).unwrap().log10(), 2);")]
+                /// ```
+                #[unstable(feature = "int_log", issue = "70887")]
+                #[must_use = "this returns the result of the operation, \
+                              without modifying the original"]
+                #[inline]
+                pub const fn log10(self) -> u32 {
+                    super::int_log10::$Int(self.0)
+                }
             }
         )+
     }
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 1dd8b0a18ab..0bb65497776 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1,5 +1,6 @@
 macro_rules! uint_impl {
-    ($SelfT:ty, $ActualT:ident, $SignedT:ident, $BITS:expr, $MaxV:expr,
+    ($SelfT:ty, $ActualT:ident, $SignedT:ident, $NonZeroT:ident,
+        $BITS:expr, $MaxV:expr,
         $rot:expr, $rot_op:expr, $rot_result:expr, $swap_op:expr, $swapped:expr,
         $reversed:expr, $le_bytes:expr, $be_bytes:expr,
         $to_xe_bytes_doc:expr, $from_xe_bytes_doc:expr) => {
@@ -839,12 +840,10 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline]
         pub const fn checked_log2(self) -> Option<u32> {
-            if self <= 0 {
-                None
+            if let Some(x) = <$NonZeroT>::new(self) {
+                Some(x.log2())
             } else {
-                // SAFETY: We just checked that this number is positive
-                let log = (Self::BITS - 1) - unsafe { intrinsics::ctlz_nonzero(self) as u32 };
-                Some(log)
+                None
             }
         }
 
@@ -863,7 +862,11 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline]
         pub const fn checked_log10(self) -> Option<u32> {
-            int_log10::$ActualT(self as $ActualT)
+            if let Some(x) = <$NonZeroT>::new(self) {
+                Some(x.log10())
+            } else {
+                None
+            }
         }
 
         /// Checked negation. Computes `-self`, returning `None` unless `self ==
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 69a0304d41d..53f7108aca3 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -13,6 +13,7 @@
 - [JSON Output](json.md)
 - [Tests](tests/index.md)
 - [Platform Support](platform-support.md)
+    - [Template for target-specific documentation](platform-support/TEMPLATE.md)
     - [aarch64-apple-ios-sim](platform-support/aarch64-apple-ios-sim.md)
     - [\*-kmc-solid_\*](platform-support/kmc-solid.md)
     - [x86_64-unknown-none](platform-support/x86_64-unknown-none.md)
diff --git a/src/doc/rustc/src/platform-support/TEMPLATE.md b/src/doc/rustc/src/platform-support/TEMPLATE.md
new file mode 100644
index 00000000000..e64783fcf19
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/TEMPLATE.md
@@ -0,0 +1,52 @@
+# `target-name-here`
+
+**Tier: 3**
+
+One-sentence description of the target (e.g. CPU, OS)
+
+## Target maintainers
+
+- Some Person, `email@example.org`, https://github.com/...
+
+## Requirements
+
+Does the target support host tools, or only cross-compilation? Does the target
+support std, or alloc (either with a default allocator, or if the user supplies
+an allocator)?
+
+Document the expectations of binaries built for the target. Do they assume
+specific minimum features beyond the baseline of the CPU/environment/etc? What
+version of the OS or environment do they expect?
+
+Are there notable `#[target_feature(...)]` or `-C target-feature=` values that
+programs may wish to use?
+
+What calling convention does `extern "C"` use on the target?
+
+What format do binaries use by default? ELF, PE, something else?
+
+## Building the target
+
+If Rust doesn't build the target by default, how can users build it? Can users
+just add it to the `target` list in `config.toml`?
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target. To compile for
+this target, you will either need to build Rust with the target enabled (see
+"Building the target" above), or build your own copy of `core` by using
+`build-std` or similar.
+
+## Testing
+
+Does the target support running binaries, or do binaries have varying
+expectations that prevent having a standard way to run them? If users can run
+binaries, can they do so in some common emulator, or do they need native
+hardware? Does the target support running the Rust testsuite?
+
+## Cross-compilation toolchains and C code
+
+Does the target support C code? If so, what toolchain target should users use
+to build compatible C code? (This may match the target triple, or it may be a
+toolchain for a different target triple, potentially with specific options or
+caveats.)
diff --git a/src/doc/rustc/src/target-tier-policy.md b/src/doc/rustc/src/target-tier-policy.md
index cc02b294b44..53d0470fa81 100644
--- a/src/doc/rustc/src/target-tier-policy.md
+++ b/src/doc/rustc/src/target-tier-policy.md
@@ -62,13 +62,22 @@ not preclude an existing target's maintainers using issues (on the Rust
 repository or otherwise) to track requirements that have not yet been met, as
 appropriate; however, before officially proposing the introduction or promotion
 of a target, it should meet all of the necessary requirements. A target
-proposal is encouraged to quote the corresponding requirements verbatim as part
-of explaining how the target meets those requirements.
+proposal must quote the corresponding requirements verbatim and respond to them
+as part of explaining how the target meets those requirements. (For the
+requirements that simply state that the target or the target developers must
+not do something, it suffices to acknowledge the requirement.)
 
 For a list of all supported targets and their corresponding tiers ("tier 3",
 "tier 2", "tier 2 with host tools", "tier 1", or "tier 1 with host tools"), see
 [platform support](platform-support.md).
 
+Several parts of this policy require providing target-specific documentation.
+Such documentation should typically appear in a subdirectory of the
+platform-support section of this rustc manual, with a link from the target's
+entry in [platform support](platform-support.md). Use
+[TEMPLATE.md](platform-support/TEMPLATE.md) as a base, and see other
+documentation in that directory for examples.
+
 Note that a target must have already received approval for the next lower tier,
 and spent a reasonable amount of time at that tier, before making a proposal
 for promotion to the next higher tier; this is true even if a target meets the
@@ -139,17 +148,19 @@ approved by the appropriate team for that shared code before acceptance.
     or binary. In other words, the introduction of the target must not cause a
     user installing or running a version of Rust or the Rust tools to be
     subject to any new license requirements.
-  - If the target supports building host tools (such as `rustc` or `cargo`),
-    those host tools must not depend on proprietary (non-FOSS) libraries, other
-    than ordinary runtime libraries supplied by the platform and commonly used
-    by other binaries built for the target. For instance, `rustc` built for the
-    target may depend on a common proprietary C runtime library or console
-    output library, but must not depend on a proprietary code generation
-    library or code optimization library. Rust's license permits such
-    combinations, but the Rust project has no interest in maintaining such
-    combinations within the scope of Rust itself, even at tier 3.
-  - Targets should not require proprietary (non-FOSS) components to link a
-    functional binary or library.
+  - Compiling, linking, and emitting functional binaries, libraries, or other
+    code for the target (whether hosted on the target itself or cross-compiling
+    from another target) must not depend on proprietary (non-FOSS) libraries.
+    Host tools built for the target itself may depend on the ordinary runtime
+    libraries supplied by the platform and commonly used by other applications
+    built for the target, but those libraries must not be required for code
+    generation for the target; cross-compilation to the target must not require
+    such libraries at all. For instance, `rustc` built for the target may
+    depend on a common proprietary C runtime library or console output library,
+    but must not depend on a proprietary code generation library or code
+    optimization library. Rust's license permits such combinations, but the
+    Rust project has no interest in maintaining such combinations within the
+    scope of Rust itself, even at tier 3.
   - "onerous" here is an intentionally subjective term. At a minimum, "onerous"
     legal/licensing terms include but are *not* limited to: non-disclosure
     requirements, non-compete requirements, contributor license agreements
@@ -184,9 +195,9 @@ approved by the appropriate team for that shared code before acceptance.
   target not implementing those portions.
 - The target must provide documentation for the Rust community explaining how
   to build for the target, using cross-compilation if possible. If the target
-  supports running tests (even if they do not pass), the documentation must
-  explain how to run tests for the target, using emulation if possible or
-  dedicated hardware if necessary.
+  supports running binaries, or running tests (even if they do not pass), the
+  documentation must explain how to run such binaries or tests for the target,
+  using emulation if possible or dedicated hardware if necessary.
 - Tier 3 targets must not impose burden on the authors of pull requests, or
   other developers in the community, to maintain the target. In particular,
   do not post comments (automated or manual) on a PR that derail or suggest a
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 3fd9c0a1944..a9a3a0af276 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -923,9 +923,7 @@ impl LangString {
 
         data.original = string.to_owned();
 
-        let tokens = Self::tokens(string).collect::<Vec<&str>>();
-
-        for token in tokens {
+        for token in Self::tokens(string) {
             match token {
                 "should_panic" => {
                     data.should_panic = true;
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index d7f33d6131c..7cc0e74a79b 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -111,6 +111,12 @@ body {
 	font: 1rem/1.4 "Source Serif 4", NanumBarunGothic, serif;
 	margin: 0;
 	position: relative;
+	/* We use overflow-wrap: break-word for Safari, which doesn't recognize
+	   `anywhere`: https://developer.mozilla.org/en-US/docs/Web/CSS/overflow-wrap */
+	overflow-wrap: break-word;
+	/* Then override it with `anywhere`, which is required to make non-Safari browsers break
+	   more aggressively when we want them to. */
+	overflow-wrap: anywhere;
 
 	-webkit-font-feature-settings: "kern", "liga";
 	-moz-font-feature-settings: "kern", "liga";
@@ -446,6 +452,7 @@ nav.sub {
 	text-align: center;
 	border-bottom: 1px solid;
 	overflow-wrap: break-word;
+	overflow-wrap: anywhere;
 	word-wrap: break-word; /* deprecated */
 	word-break: break-word; /* Chrome, non-standard */
 }
@@ -576,6 +583,7 @@ nav.sub {
 }
 
 .docblock-short {
+	overflow-wrap: break-word;
 	overflow-wrap: anywhere;
 }
 .docblock-short p {
@@ -641,6 +649,7 @@ nav.sub {
 	flex-grow: 1;
 	margin: 0px;
 	padding: 0px;
+	overflow-wrap: break-word;
 	overflow-wrap: anywhere;
 }
 
@@ -669,6 +678,7 @@ nav.sub {
 	margin: .5em 0;
 	width: calc(100% - 2px);
 	overflow-x: auto;
+	overflow-wrap: normal;
 	display: block;
 }
 
@@ -1495,6 +1505,7 @@ pre.rust {
 	padding: 4px 8px;
 	text-align: center;
 	background: rgba(0,0,0,0);
+	overflow-wrap: normal;
 }
 
 #theme-choices > button:not(:first-child) {
@@ -2099,9 +2110,14 @@ details.rustdoc-toggle[open] > summary.hideme::after {
 	}
 
 	.docblock code {
+		overflow-wrap: break-word;
 		overflow-wrap: anywhere;
 	}
 
+	.docblock table code {
+		overflow-wrap: normal;
+	}
+
 	.sub-container {
 		flex-direction: column;
 	}
diff --git a/src/test/incremental/cache_file_headers.rs b/src/test/incremental/cache_file_headers.rs
index 7f1ef886ac8..9cf611c3379 100644
--- a/src/test/incremental/cache_file_headers.rs
+++ b/src/test/incremental/cache_file_headers.rs
@@ -7,7 +7,7 @@
 
 // The `l33t haxx0r` Rust compiler is known to produce incr. comp. artifacts
 // that are outrageously incompatible with just about anything, even itself:
-//[rpass1] rustc-env:RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER="l33t haxx0r rustc 2.1 LTS"
+//[rpass1] rustc-env:RUSTC_FORCE_RUSTC_VERSION="l33t haxx0r rustc 2.1 LTS"
 
 // revisions:rpass1 rpass2
 // compile-flags: -Z query-dep-graph
diff --git a/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile b/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile
index fd66702db7f..091508cd805 100644
--- a/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile
+++ b/src/test/run-make-fulldeps/crate-hash-rustc-version/Makefile
@@ -27,7 +27,7 @@ all:
 	$(RUSTC) b.rs --extern a=$(TMPDIR)/liba$(EXT) --crate-type=bin -Crpath $(FLAGS)
 	$(call RUN,b)
 	# Now re-compile a.rs with another rustc version
-	RUSTC_FORCE_INCR_COMP_ARTIFACT_HEADER=deadfeed $(RUSTC) a.rs --crate-type=dylib $(FLAGS)
+	RUSTC_FORCE_RUSTC_VERSION=deadfeed $(RUSTC) a.rs --crate-type=dylib $(FLAGS)
 	# After compiling with a different rustc version, write symbols to disk again.
 	$(NM_CMD) $(call DYLIB,a) > $(TMPDIR)/symbolsafter
 	# As a sanity check, test if the symbols changed:
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of.rs
new file mode 100644
index 00000000000..5ba2f5ce334
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of.rs
@@ -0,0 +1,44 @@
+#![feature(rustc_attrs)]
+
+#[rustc_must_implement_one_of(eq, neq)]
+trait Equal {
+    fn eq(&self, other: &Self) -> bool {
+        !self.neq(other)
+    }
+
+    fn neq(&self, other: &Self) -> bool {
+        !self.eq(other)
+    }
+}
+
+struct T0;
+struct T1;
+struct T2;
+struct T3;
+
+impl Equal for T0 {
+    fn eq(&self, _other: &Self) -> bool {
+        true
+    }
+}
+
+impl Equal for T1 {
+    fn neq(&self, _other: &Self) -> bool {
+        false
+    }
+}
+
+impl Equal for T2 {
+    fn eq(&self, _other: &Self) -> bool {
+        true
+    }
+
+    fn neq(&self, _other: &Self) -> bool {
+        false
+    }
+}
+
+impl Equal for T3 {}
+//~^ not all trait items implemented, missing one of: `eq`, `neq`
+
+fn main() {}
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of.stderr
new file mode 100644
index 00000000000..5a4dd1388b2
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of.stderr
@@ -0,0 +1,15 @@
+error[E0046]: not all trait items implemented, missing one of: `eq`, `neq`
+  --> $DIR/rustc_must_implement_one_of.rs:41:1
+   |
+LL | impl Equal for T3 {}
+   | ^^^^^^^^^^^^^^^^^ missing one of `eq`, `neq` in implementation
+   |
+note: required because of this annotation
+  --> $DIR/rustc_must_implement_one_of.rs:3:1
+   |
+LL | #[rustc_must_implement_one_of(eq, neq)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs
new file mode 100644
index 00000000000..56e8fcff0fc
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs
@@ -0,0 +1,19 @@
+#![feature(rustc_attrs)]
+
+#[rustc_must_implement_one_of(a, a)]
+//~^ Functions names are duplicated
+trait Trait {
+    fn a() {}
+}
+
+#[rustc_must_implement_one_of(b, a, a, c, b, c)]
+//~^ Functions names are duplicated
+//~| Functions names are duplicated
+//~| Functions names are duplicated
+trait Trait1 {
+    fn a() {}
+    fn b() {}
+    fn c() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr
new file mode 100644
index 00000000000..777beba6182
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr
@@ -0,0 +1,34 @@
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:3:31
+   |
+LL | #[rustc_must_implement_one_of(a, a)]
+   |                               ^  ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:34
+   |
+LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)]
+   |                                  ^  ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:31
+   |
+LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)]
+   |                               ^           ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:40
+   |
+LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)]
+   |                                        ^     ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.rs
new file mode 100644
index 00000000000..ec2995872de
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.rs
@@ -0,0 +1,13 @@
+#[rustc_must_implement_one_of(eq, neq)]
+//~^ the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete definition of a trait, it's currently in experimental form and should be changed before being exposed outside of the std
+trait Equal {
+    fn eq(&self, other: &Self) -> bool {
+        !self.neq(other)
+    }
+
+    fn neq(&self, other: &Self) -> bool {
+        !self.eq(other)
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.stderr
new file mode 100644
index 00000000000..228bc3e35c2
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_gated.stderr
@@ -0,0 +1,11 @@
+error[E0658]: the `#[rustc_must_implement_one_of]` attribute is used to change minimal complete definition of a trait, it's currently in experimental form and should be changed before being exposed outside of the std
+  --> $DIR/rustc_must_implement_one_of_gated.rs:1:1
+   |
+LL | #[rustc_must_implement_one_of(eq, neq)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs
new file mode 100644
index 00000000000..1089e5f9c4a
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.rs
@@ -0,0 +1,38 @@
+#![feature(rustc_attrs)]
+
+#[rustc_must_implement_one_of(a, b)]
+//~^ Function not found in this trait
+//~| Function not found in this trait
+trait Tr0 {}
+
+#[rustc_must_implement_one_of(a, b)]
+//~^ Function not found in this trait
+trait Tr1 {
+    fn a() {}
+}
+
+#[rustc_must_implement_one_of(a)]
+//~^ the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args
+trait Tr2 {
+    fn a() {}
+}
+
+#[rustc_must_implement_one_of]
+//~^ malformed `rustc_must_implement_one_of` attribute input
+trait Tr3 {}
+
+#[rustc_must_implement_one_of(A, B)]
+trait Tr4 {
+    const A: u8 = 1; //~ Not a function
+
+    type B; //~ Not a function
+}
+
+#[rustc_must_implement_one_of(a, b)]
+trait Tr5 {
+    fn a(); //~ This function doesn't have a default implementation
+
+    fn b(); //~ This function doesn't have a default implementation
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr
new file mode 100644
index 00000000000..74a6dc8fec9
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_misuse.stderr
@@ -0,0 +1,82 @@
+error: malformed `rustc_must_implement_one_of` attribute input
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:20:1
+   |
+LL | #[rustc_must_implement_one_of]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[rustc_must_implement_one_of(function1, function2, ...)]`
+
+error: Function not found in this trait
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:3:31
+   |
+LL | #[rustc_must_implement_one_of(a, b)]
+   |                               ^
+
+error: Function not found in this trait
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:3:34
+   |
+LL | #[rustc_must_implement_one_of(a, b)]
+   |                                  ^
+
+error: Function not found in this trait
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:8:34
+   |
+LL | #[rustc_must_implement_one_of(a, b)]
+   |                                  ^
+
+error: the `#[rustc_must_implement_one_of]` attribute must be used with at least 2 args
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:14:1
+   |
+LL | #[rustc_must_implement_one_of(a)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: Not a function
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:26:5
+   |
+LL |     const A: u8 = 1;
+   |     ^^^^^^^^^^^^^^^^
+   |
+note: required by this annotation
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:24:1
+   |
+LL | #[rustc_must_implement_one_of(A, B)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: All `#[rustc_must_implement_one_of]` arguments must be associated function names
+
+error: Not a function
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:28:5
+   |
+LL |     type B;
+   |     ^^^^^^^
+   |
+note: required by this annotation
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:24:1
+   |
+LL | #[rustc_must_implement_one_of(A, B)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: All `#[rustc_must_implement_one_of]` arguments must be associated function names
+
+error: This function doesn't have a default implementation
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:33:5
+   |
+LL |     fn a();
+   |     ^^^^^^^
+   |
+note: required by this annotation
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:31:1
+   |
+LL | #[rustc_must_implement_one_of(a, b)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: This function doesn't have a default implementation
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:35:5
+   |
+LL |     fn b();
+   |     ^^^^^^^
+   |
+note: required by this annotation
+  --> $DIR/rustc_must_implement_one_of_misuse.rs:31:1
+   |
+LL | #[rustc_must_implement_one_of(a, b)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 9 previous errors
+