about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-09-21 17:17:25 +0000
committerbors <bors@rust-lang.org>2022-09-21 17:17:25 +0000
commitdb4b4d3becf257e7b1c051540fc7e317958d8d2d (patch)
treee6f8cb29b3451534219932f7d7dbd1d1c035ee1e
parentb79b7d8b4e0f2b112142a9ce1fea335f321a6558 (diff)
parent39bb2a79884b9e4813e2875de0910790d968f6c1 (diff)
downloadrust-db4b4d3becf257e7b1c051540fc7e317958d8d2d.tar.gz
rust-db4b4d3becf257e7b1c051540fc7e317958d8d2d.zip
Auto merge of #102097 - Dylan-DPC:rollup-gc75oh4, r=Dylan-DPC
Rollup of 7 pull requests

Successful merges:

 - #89891 (`alloc`: add unstable cfg features `no_rc` and `no_sync`)
 - #101995 (Add another example for `uN::carrying_mul`)
 - #102031 (Adding ignore fuchsia tests for Backtrace, ErrorKind cases)
 - #102041 (Improve `-Zmeta-stats` some more)
 - #102045 (fix ConstProp handling of written_only_inside_own_block_locals)
 - #102058 (Clarify Path::extension() semantics in docs abstract)
 - #102059 (Use rebind instead of dummy binder in `SameTypeModuloInfer` relation)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs365
-rw-r--r--compiler/rustc_mir_transform/src/const_prop.rs40
-rw-r--r--library/alloc/src/lib.rs9
-rw-r--r--library/core/src/num/mod.rs30
-rw-r--r--library/std/src/path.rs2
-rw-r--r--src/bootstrap/lib.rs2
-rw-r--r--src/test/mir-opt/issue-101973.rs20
-rw-r--r--src/test/mir-opt/issue_101973.inner.ConstProp.diff100
-rw-r--r--src/test/run-make-fulldeps/alloc-no-rc/Makefile4
-rw-r--r--src/test/run-make-fulldeps/alloc-no-sync/Makefile4
-rw-r--r--src/test/ui/backtrace.rs1
-rw-r--r--src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr2
-rw-r--r--src/test/ui/panics/issue-47429-short-backtraces.rs1
-rw-r--r--src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr2
-rw-r--r--src/test/ui/panics/runtime-switch.legacy.run.stderr2
-rw-r--r--src/test/ui/panics/runtime-switch.rs1
-rw-r--r--src/test/ui/panics/runtime-switch.v0.run.stderr2
-rw-r--r--src/test/ui/process/process-spawn-nonexistent.rs1
-rw-r--r--src/test/ui/runtime/backtrace-debuginfo.rs1
-rw-r--r--src/test/ui/std-backtrace.rs1
-rw-r--r--src/test/ui/suggestions/issue-101984.rs27
-rw-r--r--src/test/ui/suggestions/issue-101984.stderr14
23 files changed, 391 insertions, 242 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 546ab82bc23..18255a5089c 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -2765,7 +2765,7 @@ impl<'tcx> TypeRelation<'tcx> for SameTypeModuloInfer<'_, 'tcx> {
     where
         T: relate::Relate<'tcx>,
     {
-        Ok(ty::Binder::dummy(self.relate(a.skip_binder(), b.skip_binder())?))
+        Ok(a.rebind(self.relate(a.skip_binder(), b.skip_binder())?))
     }
 
     fn consts(
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 5a60ea794ed..67c28461ce5 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -28,6 +28,7 @@ use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, SymbolName, Ty, TyCtxt};
+use rustc_middle::util::common::to_readable_str;
 use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
 use rustc_session::config::CrateType;
 use rustc_session::cstore::{ForeignModule, LinkagePreference, NativeLib};
@@ -261,10 +262,10 @@ impl<'a, 'tcx> Encodable<EncodeContext<'a, 'tcx>> for Span {
         // This allows us to avoid loading the dependencies of proc-macro crates: all of
         // the information we need to decode `Span`s is stored in the proc-macro crate.
         let (tag, metadata_index) = if source_file.is_imported() && !s.is_proc_macro {
-            // To simplify deserialization, we 'rebase' this span onto the crate it originally came from
-            // (the crate that 'owns' the file it references. These rebased 'lo' and 'hi' values
-            // are relative to the source map information for the 'foreign' crate whose CrateNum
-            // we write into the metadata. This allows `imported_source_files` to binary
+            // To simplify deserialization, we 'rebase' this span onto the crate it originally came
+            // from (the crate that 'owns' the file it references. These rebased 'lo' and 'hi'
+            // values are relative to the source map information for the 'foreign' crate whose
+            // CrateNum we write into the metadata. This allows `imported_source_files` to binary
             // search through the 'foreign' crate's source map information, using the
             // deserialized 'lo' and 'hi' values directly.
             //
@@ -554,78 +555,56 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
     fn encode_crate_root(&mut self) -> LazyValue<CrateRoot> {
         let tcx = self.tcx;
-        let mut i = 0;
-        let preamble_bytes = self.position() - i;
-
-        // Encode the crate deps
-        i = self.position();
-        let crate_deps = self.encode_crate_deps();
-        let dylib_dependency_formats = self.encode_dylib_dependency_formats();
-        let dep_bytes = self.position() - i;
-
-        // Encode the lib features.
-        i = self.position();
-        let lib_features = self.encode_lib_features();
-        let lib_feature_bytes = self.position() - i;
-
-        // Encode the stability implications.
-        i = self.position();
-        let stability_implications = self.encode_stability_implications();
-        let stability_implications_bytes = self.position() - i;
-
-        // Encode the language items.
-        i = self.position();
-        let lang_items = self.encode_lang_items();
-        let lang_items_missing = self.encode_lang_items_missing();
-        let lang_item_bytes = self.position() - i;
-
-        // Encode the diagnostic items.
-        i = self.position();
-        let diagnostic_items = self.encode_diagnostic_items();
-        let diagnostic_item_bytes = self.position() - i;
-
-        // Encode the native libraries used
-        i = self.position();
-        let native_libraries = self.encode_native_libraries();
-        let native_lib_bytes = self.position() - i;
-
-        i = self.position();
-        let foreign_modules = self.encode_foreign_modules();
-        let foreign_modules_bytes = self.position() - i;
-
-        // Encode DefPathTable
-        i = self.position();
-        self.encode_def_path_table();
-        let def_path_table_bytes = self.position() - i;
+        let mut stats: Vec<(&'static str, usize)> = Vec::with_capacity(32);
+
+        macro_rules! stat {
+            ($label:literal, $f:expr) => {{
+                let orig_pos = self.position();
+                let res = $f();
+                stats.push(($label, self.position() - orig_pos));
+                res
+            }};
+        }
+
+        // We have already encoded some things. Get their combined size from the current position.
+        stats.push(("preamble", self.position()));
+
+        let (crate_deps, dylib_dependency_formats) =
+            stat!("dep", || (self.encode_crate_deps(), self.encode_dylib_dependency_formats()));
+
+        let lib_features = stat!("lib-features", || self.encode_lib_features());
+
+        let stability_implications =
+            stat!("stability-implications", || self.encode_stability_implications());
+
+        let (lang_items, lang_items_missing) = stat!("lang-items", || {
+            (self.encode_lang_items(), self.encode_lang_items_missing())
+        });
+
+        let diagnostic_items = stat!("diagnostic-items", || self.encode_diagnostic_items());
+
+        let native_libraries = stat!("native-libs", || self.encode_native_libraries());
+
+        let foreign_modules = stat!("foreign-modules", || self.encode_foreign_modules());
+
+        _ = stat!("def-path-table", || self.encode_def_path_table());
 
         // Encode the def IDs of traits, for rustdoc and diagnostics.
-        i = self.position();
-        let traits = self.encode_traits();
-        let traits_bytes = self.position() - i;
+        let traits = stat!("traits", || self.encode_traits());
 
         // Encode the def IDs of impls, for coherence checking.
-        i = self.position();
-        let impls = self.encode_impls();
-        let impls_bytes = self.position() - i;
-
-        i = self.position();
-        let incoherent_impls = self.encode_incoherent_impls();
-        let incoherent_impls_bytes = self.position() - i;
-
-        // Encode MIR.
-        i = self.position();
-        self.encode_mir();
-        let mir_bytes = self.position() - i;
-
-        // Encode the items.
-        i = self.position();
-        self.encode_def_ids();
-        self.encode_info_for_items();
-        let item_bytes = self.position() - i;
-
-        // Encode the allocation index
-        i = self.position();
-        let interpret_alloc_index = {
+        let impls = stat!("impls", || self.encode_impls());
+
+        let incoherent_impls = stat!("incoherent-impls", || self.encode_incoherent_impls());
+
+        _ = stat!("mir", || self.encode_mir());
+
+        _ = stat!("items", || {
+            self.encode_def_ids();
+            self.encode_info_for_items();
+        });
+
+        let interpret_alloc_index = stat!("interpret-alloc-index", || {
             let mut interpret_alloc_index = Vec::new();
             let mut n = 0;
             trace!("beginning to encode alloc ids");
@@ -646,126 +625,90 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 n = new_n;
             }
             self.lazy_array(interpret_alloc_index)
-        };
-        let interpret_alloc_index_bytes = self.position() - i;
+        });
 
-        // Encode the proc macro data. This affects 'tables',
-        // so we need to do this before we encode the tables.
-        // This overwrites def_keys, so it must happen after encode_def_path_table.
-        i = self.position();
-        let proc_macro_data = self.encode_proc_macros();
-        let proc_macro_data_bytes = self.position() - i;
+        // Encode the proc macro data. This affects `tables`, so we need to do this before we
+        // encode the tables. This overwrites def_keys, so it must happen after
+        // encode_def_path_table.
+        let proc_macro_data = stat!("proc-macro-data", || self.encode_proc_macros());
 
-        i = self.position();
-        let tables = self.tables.encode(&mut self.opaque);
-        let tables_bytes = self.position() - i;
+        let tables = stat!("tables", || self.tables.encode(&mut self.opaque));
 
-        i = self.position();
-        let debugger_visualizers = self.encode_debugger_visualizers();
-        let debugger_visualizers_bytes = self.position() - i;
+        let debugger_visualizers =
+            stat!("debugger-visualizers", || self.encode_debugger_visualizers());
 
         // Encode exported symbols info. This is prefetched in `encode_metadata` so we encode
         // this as late as possible to give the prefetching as much time as possible to complete.
-        i = self.position();
-        let exported_symbols = tcx.exported_symbols(LOCAL_CRATE);
-        let exported_symbols = self.encode_exported_symbols(&exported_symbols);
-        let exported_symbols_bytes = self.position() - i;
-
-        // Encode the hygiene data,
-        // IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The process
-        // of encoding other items (e.g. `optimized_mir`) may cause us to load
-        // data from the incremental cache. If this causes us to deserialize a `Span`,
-        // then we may load additional `SyntaxContext`s into the global `HygieneData`.
-        // Therefore, we need to encode the hygiene data last to ensure that we encode
-        // any `SyntaxContext`s that might be used.
-        i = self.position();
-        let (syntax_contexts, expn_data, expn_hashes) = self.encode_hygiene();
-        let hygiene_bytes = self.position() - i;
-
-        i = self.position();
-        let def_path_hash_map = self.encode_def_path_hash_map();
-        let def_path_hash_map_bytes = self.position() - i;
-
-        // Encode source_map. This needs to be done last,
-        // since encoding `Span`s tells us which `SourceFiles` we actually
-        // need to encode.
-        i = self.position();
-        let source_map = self.encode_source_map();
-        let source_map_bytes = self.position() - i;
-
-        i = self.position();
-        let attrs = tcx.hir().krate_attrs();
-        let has_default_lib_allocator = tcx.sess.contains_name(&attrs, sym::default_lib_allocator);
-        let root = self.lazy(CrateRoot {
-            name: tcx.crate_name(LOCAL_CRATE),
-            extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
-            triple: tcx.sess.opts.target_triple.clone(),
-            hash: tcx.crate_hash(LOCAL_CRATE),
-            stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
-            required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE),
-            panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
-            edition: tcx.sess.edition(),
-            has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
-            has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
-            has_default_lib_allocator,
-            proc_macro_data,
-            debugger_visualizers,
-            compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
-            needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
-            needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
-            no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
-            panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
-            profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
-            symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
-
-            crate_deps,
-            dylib_dependency_formats,
-            lib_features,
-            stability_implications,
-            lang_items,
-            diagnostic_items,
-            lang_items_missing,
-            native_libraries,
-            foreign_modules,
-            source_map,
-            traits,
-            impls,
-            incoherent_impls,
-            exported_symbols,
-            interpret_alloc_index,
-            tables,
-            syntax_contexts,
-            expn_data,
-            expn_hashes,
-            def_path_hash_map,
+        let exported_symbols = stat!("exported-symbols", || {
+            self.encode_exported_symbols(&tcx.exported_symbols(LOCAL_CRATE))
+        });
+
+        // Encode the hygiene data.
+        // IMPORTANT: this *must* be the last thing that we encode (other than `SourceMap`). The
+        // process of encoding other items (e.g. `optimized_mir`) may cause us to load data from
+        // the incremental cache. If this causes us to deserialize a `Span`, then we may load
+        // additional `SyntaxContext`s into the global `HygieneData`. Therefore, we need to encode
+        // the hygiene data last to ensure that we encode any `SyntaxContext`s that might be used.
+        let (syntax_contexts, expn_data, expn_hashes) = stat!("hygiene", || self.encode_hygiene());
+
+        let def_path_hash_map = stat!("def-path-hash-map", || self.encode_def_path_hash_map());
+
+        // Encode source_map. This needs to be done last, because encoding `Span`s tells us which
+        // `SourceFiles` we actually need to encode.
+        let source_map = stat!("source-map", || self.encode_source_map());
+
+        let root = stat!("final", || {
+            let attrs = tcx.hir().krate_attrs();
+            self.lazy(CrateRoot {
+                name: tcx.crate_name(LOCAL_CRATE),
+                extra_filename: tcx.sess.opts.cg.extra_filename.clone(),
+                triple: tcx.sess.opts.target_triple.clone(),
+                hash: tcx.crate_hash(LOCAL_CRATE),
+                stable_crate_id: tcx.def_path_hash(LOCAL_CRATE.as_def_id()).stable_crate_id(),
+                required_panic_strategy: tcx.required_panic_strategy(LOCAL_CRATE),
+                panic_in_drop_strategy: tcx.sess.opts.unstable_opts.panic_in_drop,
+                edition: tcx.sess.edition(),
+                has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
+                has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
+                has_default_lib_allocator: tcx
+                    .sess
+                    .contains_name(&attrs, sym::default_lib_allocator),
+                proc_macro_data,
+                debugger_visualizers,
+                compiler_builtins: tcx.sess.contains_name(&attrs, sym::compiler_builtins),
+                needs_allocator: tcx.sess.contains_name(&attrs, sym::needs_allocator),
+                needs_panic_runtime: tcx.sess.contains_name(&attrs, sym::needs_panic_runtime),
+                no_builtins: tcx.sess.contains_name(&attrs, sym::no_builtins),
+                panic_runtime: tcx.sess.contains_name(&attrs, sym::panic_runtime),
+                profiler_runtime: tcx.sess.contains_name(&attrs, sym::profiler_runtime),
+                symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
+
+                crate_deps,
+                dylib_dependency_formats,
+                lib_features,
+                stability_implications,
+                lang_items,
+                diagnostic_items,
+                lang_items_missing,
+                native_libraries,
+                foreign_modules,
+                source_map,
+                traits,
+                impls,
+                incoherent_impls,
+                exported_symbols,
+                interpret_alloc_index,
+                tables,
+                syntax_contexts,
+                expn_data,
+                expn_hashes,
+                def_path_hash_map,
+            })
         });
-        let final_bytes = self.position() - i;
 
         let total_bytes = self.position();
 
-        let computed_total_bytes = preamble_bytes
-            + dep_bytes
-            + lib_feature_bytes
-            + stability_implications_bytes
-            + lang_item_bytes
-            + diagnostic_item_bytes
-            + native_lib_bytes
-            + foreign_modules_bytes
-            + def_path_table_bytes
-            + traits_bytes
-            + impls_bytes
-            + incoherent_impls_bytes
-            + mir_bytes
-            + item_bytes
-            + interpret_alloc_index_bytes
-            + proc_macro_data_bytes
-            + tables_bytes
-            + debugger_visualizers_bytes
-            + exported_symbols_bytes
-            + hygiene_bytes
-            + def_path_hash_map_bytes
-            + source_map_bytes
-            + final_bytes;
+        let computed_total_bytes: usize = stats.iter().map(|(_, size)| size).sum();
         assert_eq!(total_bytes, computed_total_bytes);
 
         if tcx.sess.meta_stats() {
@@ -783,42 +726,38 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             assert_eq!(self.opaque.file().stream_position().unwrap(), pos_before_rewind);
 
+            stats.sort_by_key(|&(_, usize)| usize);
+
+            let prefix = "meta-stats";
             let perc = |bytes| (bytes * 100) as f64 / total_bytes as f64;
-            let p = |label, bytes| {
-                eprintln!("{:>21}: {:>8} bytes ({:4.1}%)", label, bytes, perc(bytes));
-            };
 
-            eprintln!("");
+            eprintln!("{} METADATA STATS", prefix);
+            eprintln!("{} {:<23}{:>10}", prefix, "Section", "Size");
+            eprintln!(
+                "{} ----------------------------------------------------------------",
+                prefix
+            );
+            for (label, size) in stats {
+                eprintln!(
+                    "{} {:<23}{:>10} ({:4.1}%)",
+                    prefix,
+                    label,
+                    to_readable_str(size),
+                    perc(size)
+                );
+            }
+            eprintln!(
+                "{} ----------------------------------------------------------------",
+                prefix
+            );
             eprintln!(
-                "{} metadata bytes, of which {} bytes ({:.1}%) are zero",
-                total_bytes,
-                zero_bytes,
+                "{} {:<23}{:>10} (of which {:.1}% are zero bytes)",
+                prefix,
+                "Total",
+                to_readable_str(total_bytes),
                 perc(zero_bytes)
             );
-            p("preamble", preamble_bytes);
-            p("dep", dep_bytes);
-            p("lib feature", lib_feature_bytes);
-            p("stability_implications", stability_implications_bytes);
-            p("lang item", lang_item_bytes);
-            p("diagnostic item", diagnostic_item_bytes);
-            p("native lib", native_lib_bytes);
-            p("foreign modules", foreign_modules_bytes);
-            p("def-path table", def_path_table_bytes);
-            p("traits", traits_bytes);
-            p("impls", impls_bytes);
-            p("incoherent_impls", incoherent_impls_bytes);
-            p("mir", mir_bytes);
-            p("item", item_bytes);
-            p("interpret_alloc_index", interpret_alloc_index_bytes);
-            p("proc-macro-data", proc_macro_data_bytes);
-            p("tables", tables_bytes);
-            p("debugger visualizers", debugger_visualizers_bytes);
-            p("exported symbols", exported_symbols_bytes);
-            p("hygiene", hygiene_bytes);
-            p("def-path hashes", def_path_hash_map_bytes);
-            p("source_map", source_map_bytes);
-            p("final", final_bytes);
-            eprintln!("");
+            eprintln!("{}", prefix);
         }
 
         root
diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs
index cb134a20ea0..4a9bd9df327 100644
--- a/compiler/rustc_mir_transform/src/const_prop.rs
+++ b/compiler/rustc_mir_transform/src/const_prop.rs
@@ -1066,32 +1066,32 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
         let source_info = terminator.source_info;
         self.source_info = Some(source_info);
         self.super_terminator(terminator, location);
+        // Do NOT early return in this function, it does some crucial fixup of the state at the end!
         match &mut terminator.kind {
             TerminatorKind::Assert { expected, ref mut cond, .. } => {
                 if let Some(ref value) = self.eval_operand(&cond) {
                     trace!("assertion on {:?} should be {:?}", value, expected);
                     let expected = Scalar::from_bool(*expected);
-                    let Ok(value_const) = self.ecx.read_scalar(&value) else {
-                        // FIXME should be used use_ecx rather than a local match... but we have
-                        // quite a few of these read_scalar/read_immediate that need fixing.
-                        return
-                    };
-                    if expected != value_const {
-                        // Poison all places this operand references so that further code
-                        // doesn't use the invalid value
-                        match cond {
-                            Operand::Move(ref place) | Operand::Copy(ref place) => {
-                                Self::remove_const(&mut self.ecx, place.local);
+                    // FIXME should be used use_ecx rather than a local match... but we have
+                    // quite a few of these read_scalar/read_immediate that need fixing.
+                    if let Ok(value_const) = self.ecx.read_scalar(&value) {
+                        if expected != value_const {
+                            // Poison all places this operand references so that further code
+                            // doesn't use the invalid value
+                            match cond {
+                                Operand::Move(ref place) | Operand::Copy(ref place) => {
+                                    Self::remove_const(&mut self.ecx, place.local);
+                                }
+                                Operand::Constant(_) => {}
+                            }
+                        } else {
+                            if self.should_const_prop(value) {
+                                *cond = self.operand_from_scalar(
+                                    value_const,
+                                    self.tcx.types.bool,
+                                    source_info.span,
+                                );
                             }
-                            Operand::Constant(_) => {}
-                        }
-                    } else {
-                        if self.should_const_prop(value) {
-                            *cond = self.operand_from_scalar(
-                                value_const,
-                                self.tcx.types.bool,
-                                source_info.span,
-                            );
                         }
                     }
                 }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index ce71cd600fc..6b3b1c22222 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -69,6 +69,8 @@
     any(not(feature = "miri-test-libstd"), test, doctest),
     no_global_oom_handling,
     not(no_global_oom_handling),
+    not(no_rc),
+    not(no_sync),
     target_has_atomic = "ptr"
 ))]
 #![no_std]
@@ -225,16 +227,17 @@ mod boxed {
 }
 pub mod borrow;
 pub mod collections;
-#[cfg(not(no_global_oom_handling))]
+#[cfg(all(not(no_rc), not(no_sync), not(no_global_oom_handling)))]
 pub mod ffi;
 pub mod fmt;
+#[cfg(not(no_rc))]
 pub mod rc;
 pub mod slice;
 pub mod str;
 pub mod string;
-#[cfg(target_has_atomic = "ptr")]
+#[cfg(all(not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
 pub mod sync;
-#[cfg(all(not(no_global_oom_handling), target_has_atomic = "ptr"))]
+#[cfg(all(not(no_global_oom_handling), not(no_rc), not(no_sync), target_has_atomic = "ptr"))]
 pub mod task;
 #[cfg(test)]
 mod tests;
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index ab17aa0c830..dd4409198e3 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -113,6 +113,9 @@ macro_rules! widening_impl {
         /// This returns the low-order (wrapping) bits and the high-order (overflow) bits
         /// of the result as two separate values, in that order.
         ///
+        /// If you also need to add a carry to the wide result, then you want
+        /// [`Self::carrying_mul`] instead.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -148,6 +151,8 @@ macro_rules! widening_impl {
         /// additional amount of overflow. This allows for chaining together multiple
         /// multiplications to create "big integers" which represent larger values.
         ///
+        /// If you don't need the `carry`, then you can use [`Self::widening_mul`] instead.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -167,6 +172,31 @@ macro_rules! widening_impl {
         )]
         /// ```
         ///
+        /// This is the core operation needed for scalar multiplication when
+        /// implementing it for wider-than-native types.
+        ///
+        /// ```
+        /// #![feature(bigint_helper_methods)]
+        /// fn scalar_mul_eq(little_endian_digits: &mut Vec<u16>, multiplicand: u16) {
+        ///     let mut carry = 0;
+        ///     for d in little_endian_digits.iter_mut() {
+        ///         (*d, carry) = d.carrying_mul(multiplicand, carry);
+        ///     }
+        ///     if carry != 0 {
+        ///         little_endian_digits.push(carry);
+        ///     }
+        /// }
+        ///
+        /// let mut v = vec![10, 20];
+        /// scalar_mul_eq(&mut v, 3);
+        /// assert_eq!(v, [30, 60]);
+        ///
+        /// assert_eq!(0x87654321_u64 * 0xFEED, 0x86D3D159E38D);
+        /// let mut v = vec![0x4321, 0x8765];
+        /// scalar_mul_eq(&mut v, 0xFEED);
+        /// assert_eq!(v, [0xE38D, 0xD159, 0x86D3]);
+        /// ```
+        ///
         /// If `carry` is zero, this is similar to [`overflowing_mul`](Self::overflowing_mul),
         /// except that it gives the value of the overflow instead of just whether one happened:
         ///
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 5dfeb517a19..4f9dff1ef03 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2401,7 +2401,7 @@ impl Path {
         self.file_name().map(split_file_at_dot).and_then(|(before, _after)| Some(before))
     }
 
-    /// Extracts the extension of [`self.file_name`], if possible.
+    /// Extracts the extension (without the leading dot) of [`self.file_name`], if possible.
     ///
     /// The extension is:
     ///
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index b7d271e6494..0464dbde065 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -201,6 +201,8 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &'static str, Option<&[&'static str]>)]
     (Some(Mode::Std), "stdarch_intel_sde", None),
     (Some(Mode::Std), "no_fp_fmt_parse", None),
     (Some(Mode::Std), "no_global_oom_handling", None),
+    (Some(Mode::Std), "no_rc", None),
+    (Some(Mode::Std), "no_sync", None),
     (Some(Mode::Std), "freebsd12", None),
     (Some(Mode::Std), "backtrace_in_libstd", None),
     /* Extra values not defined in the built-in targets yet, but used in std */
diff --git a/src/test/mir-opt/issue-101973.rs b/src/test/mir-opt/issue-101973.rs
new file mode 100644
index 00000000000..216659a235e
--- /dev/null
+++ b/src/test/mir-opt/issue-101973.rs
@@ -0,0 +1,20 @@
+// compile-flags: -O -C debug-assertions=on
+// This needs inlining followed by ConstProp to reproduce, so we cannot use "unit-test".
+
+#[inline]
+pub fn imm8(x: u32) -> u32 {
+    let mut out = 0u32;
+    out |= (x >> 0) & 0xff;
+    out
+}
+
+// EMIT_MIR issue_101973.inner.ConstProp.diff
+#[inline(never)]
+pub fn inner(fields: u32) -> i64 {
+    imm8(fields).rotate_right(((fields >> 8) & 0xf) << 1) as i32 as i64
+}
+
+fn main() {
+    let val = inner(0xe32cf20f);
+    assert_eq!(val as u64, 0xfffffffff0000000);
+}
diff --git a/src/test/mir-opt/issue_101973.inner.ConstProp.diff b/src/test/mir-opt/issue_101973.inner.ConstProp.diff
new file mode 100644
index 00000000000..89733a9a2cb
--- /dev/null
+++ b/src/test/mir-opt/issue_101973.inner.ConstProp.diff
@@ -0,0 +1,100 @@
+- // MIR for `inner` before ConstProp
++ // MIR for `inner` after ConstProp
+  
+  fn inner(_1: u32) -> i64 {
+      debug fields => _1;                  // in scope 0 at $DIR/issue-101973.rs:+0:14: +0:20
+      let mut _0: i64;                     // return place in scope 0 at $DIR/issue-101973.rs:+0:30: +0:33
+      let mut _2: i32;                     // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
+      let mut _3: u32;                     // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:58
+      let mut _4: u32;                     // in scope 0 at $DIR/issue-101973.rs:+1:5: +1:17
+      let mut _5: u32;                     // in scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
+      let mut _6: u32;                     // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+      let mut _7: u32;                     // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
+      let mut _8: u32;                     // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+      let mut _9: u32;                     // in scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
+      let mut _10: (u32, bool);            // in scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+      let mut _11: (u32, bool);            // in scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+      scope 1 (inlined imm8) {             // at $DIR/issue-101973.rs:14:5: 14:17
+          debug x => _5;                   // in scope 1 at $DIR/issue-101973.rs:5:13: 5:14
+          let mut _12: u32;                // in scope 1 at $DIR/issue-101973.rs:7:12: 7:27
+          let mut _13: u32;                // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20
+          let mut _14: u32;                // in scope 1 at $DIR/issue-101973.rs:7:13: 7:14
+          let mut _15: (u32, bool);        // in scope 1 at $DIR/issue-101973.rs:7:12: 7:20
+          scope 2 {
+              debug out => _4;             // in scope 2 at $DIR/issue-101973.rs:6:9: 6:16
+          }
+      }
+      scope 3 (inlined core::num::<impl u32>::rotate_right) { // at $DIR/issue-101973.rs:14:5: 14:58
+          debug self => _4;                // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          debug n => _6;                   // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          let mut _16: u32;                // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          let mut _17: u32;                // in scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+      }
+  
+      bb0: {
+          StorageLive(_2);                 // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
+          StorageLive(_3);                 // scope 0 at $DIR/issue-101973.rs:+1:5: +1:58
+          StorageLive(_4);                 // scope 0 at $DIR/issue-101973.rs:+1:5: +1:17
+          StorageLive(_5);                 // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
+          _5 = _1;                         // scope 0 at $DIR/issue-101973.rs:+1:10: +1:16
+          _4 = const 0_u32;                // scope 1 at $DIR/issue-101973.rs:6:19: 6:23
+          StorageLive(_12);                // scope 2 at $DIR/issue-101973.rs:7:12: 7:27
+          StorageLive(_13);                // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+          StorageLive(_14);                // scope 2 at $DIR/issue-101973.rs:7:13: 7:14
+          _14 = _5;                        // scope 2 at $DIR/issue-101973.rs:7:13: 7:14
+          _15 = CheckedShr(_14, const 0_i32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+          assert(!move (_15.1: bool), "attempt to shift right by `{}`, which would overflow", const 0_i32) -> bb3; // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+      }
+  
+      bb1: {
+          _8 = move (_10.0: u32);          // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+          StorageDead(_9);                 // scope 0 at $DIR/issue-101973.rs:+1:44: +1:45
+          _7 = BitAnd(move _8, const 15_u32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
+          StorageDead(_8);                 // scope 0 at $DIR/issue-101973.rs:+1:51: +1:52
+          _11 = CheckedShl(_7, const 1_i32); // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+          assert(!move (_11.1: bool), "attempt to shift left by `{}`, which would overflow", const 1_i32) -> bb2; // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+      }
+  
+      bb2: {
+          _6 = move (_11.0: u32);          // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+          StorageDead(_7);                 // scope 0 at $DIR/issue-101973.rs:+1:56: +1:57
+          StorageLive(_16);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          _16 = _4;                        // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          StorageLive(_17);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          _17 = _6;                        // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          _3 = rotate_right::<u32>(move _16, move _17) -> bb4; // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                                           // mir::Constant
+                                           // + span: $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+                                           // + literal: Const { ty: extern "rust-intrinsic" fn(u32, u32) -> u32 {rotate_right::<u32>}, val: Value(<ZST>) }
+      }
+  
+      bb3: {
+          _13 = move (_15.0: u32);         // scope 2 at $DIR/issue-101973.rs:7:12: 7:20
+          StorageDead(_14);                // scope 2 at $DIR/issue-101973.rs:7:19: 7:20
+          _12 = BitAnd(move _13, const 255_u32); // scope 2 at $DIR/issue-101973.rs:7:12: 7:27
+          StorageDead(_13);                // scope 2 at $DIR/issue-101973.rs:7:26: 7:27
+          _4 = BitOr(_4, move _12);        // scope 2 at $DIR/issue-101973.rs:7:5: 7:27
+          StorageDead(_12);                // scope 2 at $DIR/issue-101973.rs:7:26: 7:27
+          StorageDead(_5);                 // scope 0 at $DIR/issue-101973.rs:+1:16: +1:17
+          StorageLive(_6);                 // scope 0 at $DIR/issue-101973.rs:+1:31: +1:57
+          StorageLive(_7);                 // scope 0 at $DIR/issue-101973.rs:+1:31: +1:52
+          StorageLive(_8);                 // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+          StorageLive(_9);                 // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
+          _9 = _1;                         // scope 0 at $DIR/issue-101973.rs:+1:33: +1:39
+          _10 = CheckedShr(_9, const 8_i32); // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+          assert(!move (_10.1: bool), "attempt to shift right by `{}`, which would overflow", const 8_i32) -> bb1; // scope 0 at $DIR/issue-101973.rs:+1:32: +1:45
+      }
+  
+      bb4: {
+          StorageDead(_17);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          StorageDead(_16);                // scope 3 at $SRC_DIR/core/src/num/uint_macros.rs:LL:COL
+          StorageDead(_6);                 // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58
+          StorageDead(_4);                 // scope 0 at $DIR/issue-101973.rs:+1:57: +1:58
+          _2 = move _3 as i32 (Misc);      // scope 0 at $DIR/issue-101973.rs:+1:5: +1:65
+          StorageDead(_3);                 // scope 0 at $DIR/issue-101973.rs:+1:64: +1:65
+          _0 = move _2 as i64 (Misc);      // scope 0 at $DIR/issue-101973.rs:+1:5: +1:72
+          StorageDead(_2);                 // scope 0 at $DIR/issue-101973.rs:+1:71: +1:72
+          return;                          // scope 0 at $DIR/issue-101973.rs:+2:2: +2:2
+      }
+  }
+  
diff --git a/src/test/run-make-fulldeps/alloc-no-rc/Makefile b/src/test/run-make-fulldeps/alloc-no-rc/Makefile
new file mode 100644
index 00000000000..5f7ae70fa02
--- /dev/null
+++ b/src/test/run-make-fulldeps/alloc-no-rc/Makefile
@@ -0,0 +1,4 @@
+include ../tools.mk
+
+all:
+	$(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_rc
diff --git a/src/test/run-make-fulldeps/alloc-no-sync/Makefile b/src/test/run-make-fulldeps/alloc-no-sync/Makefile
new file mode 100644
index 00000000000..6a258a2ddfd
--- /dev/null
+++ b/src/test/run-make-fulldeps/alloc-no-sync/Makefile
@@ -0,0 +1,4 @@
+include ../tools.mk
+
+all:
+	$(RUSTC) --edition=2021 -Dwarnings --crate-type=rlib ../../../../library/alloc/src/lib.rs --cfg no_sync
diff --git a/src/test/ui/backtrace.rs b/src/test/ui/backtrace.rs
index e2ac43fffc9..dd73dd9886a 100644
--- a/src/test/ui/backtrace.rs
+++ b/src/test/ui/backtrace.rs
@@ -4,6 +4,7 @@
 // ignore-openbsd no support for libbacktrace without filename
 // ignore-sgx no processes
 // ignore-msvc see #62897 and `backtrace-debuginfo.rs` test
+// ignore-fuchsia Backtraces not symbolized
 // compile-flags:-g
 // compile-flags:-Cstrip=none
 
diff --git a/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr b/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr
index b6223b93764..ac4ed8225bd 100644
--- a/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr
+++ b/src/test/ui/panics/issue-47429-short-backtraces.legacy.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:22:5
+thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:23:5
 stack backtrace:
    0: std::panicking::begin_panic
    1: issue_47429_short_backtraces::main
diff --git a/src/test/ui/panics/issue-47429-short-backtraces.rs b/src/test/ui/panics/issue-47429-short-backtraces.rs
index f338ace6bb0..58d0fa62c34 100644
--- a/src/test/ui/panics/issue-47429-short-backtraces.rs
+++ b/src/test/ui/panics/issue-47429-short-backtraces.rs
@@ -12,6 +12,7 @@
 // ignore-wasm no panic or subprocess support
 // ignore-emscripten no panic or subprocess support
 // ignore-sgx no subprocess support
+// ignore-fuchsia Backtraces not symbolized
 
 // NOTE(eddyb) output differs between symbol mangling schemes
 // revisions: legacy v0
diff --git a/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr b/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr
index c2bea449249..65401fe1c3d 100644
--- a/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr
+++ b/src/test/ui/panics/issue-47429-short-backtraces.v0.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:22:5
+thread 'main' panicked at 'explicit panic', $DIR/issue-47429-short-backtraces.rs:23:5
 stack backtrace:
    0: std::panicking::begin_panic::<&str>
    1: issue_47429_short_backtraces::main
diff --git a/src/test/ui/panics/runtime-switch.legacy.run.stderr b/src/test/ui/panics/runtime-switch.legacy.run.stderr
index f282f18839c..0f76551630c 100644
--- a/src/test/ui/panics/runtime-switch.legacy.run.stderr
+++ b/src/test/ui/panics/runtime-switch.legacy.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:25:5
+thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:26:5
 stack backtrace:
    0: std::panicking::begin_panic
    1: runtime_switch::main
diff --git a/src/test/ui/panics/runtime-switch.rs b/src/test/ui/panics/runtime-switch.rs
index 37ef961e2d0..882340e495c 100644
--- a/src/test/ui/panics/runtime-switch.rs
+++ b/src/test/ui/panics/runtime-switch.rs
@@ -12,6 +12,7 @@
 // ignore-wasm no panic or subprocess support
 // ignore-emscripten no panic or subprocess support
 // ignore-sgx no subprocess support
+// ignore-fuchsia Backtrace not symbolized
 
 // NOTE(eddyb) output differs between symbol mangling schemes
 // revisions: legacy v0
diff --git a/src/test/ui/panics/runtime-switch.v0.run.stderr b/src/test/ui/panics/runtime-switch.v0.run.stderr
index 7ce9722e5ed..a4ae441317d 100644
--- a/src/test/ui/panics/runtime-switch.v0.run.stderr
+++ b/src/test/ui/panics/runtime-switch.v0.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:25:5
+thread 'main' panicked at 'explicit panic', $DIR/runtime-switch.rs:26:5
 stack backtrace:
    0: std::panicking::begin_panic::<&str>
    1: runtime_switch::main
diff --git a/src/test/ui/process/process-spawn-nonexistent.rs b/src/test/ui/process/process-spawn-nonexistent.rs
index a513722639a..9dd608986df 100644
--- a/src/test/ui/process/process-spawn-nonexistent.rs
+++ b/src/test/ui/process/process-spawn-nonexistent.rs
@@ -1,6 +1,7 @@
 // run-pass
 // ignore-emscripten no processes
 // ignore-sgx no processes
+// ignore-fuchsia ErrorKind not translated
 
 use std::io::ErrorKind;
 use std::process::Command;
diff --git a/src/test/ui/runtime/backtrace-debuginfo.rs b/src/test/ui/runtime/backtrace-debuginfo.rs
index 7c9f1a7f2f4..8b5466b6cfa 100644
--- a/src/test/ui/runtime/backtrace-debuginfo.rs
+++ b/src/test/ui/runtime/backtrace-debuginfo.rs
@@ -12,6 +12,7 @@
 // ignore-pretty issue #37195
 // ignore-emscripten spawning processes is not supported
 // ignore-sgx no processes
+// ignore-fuchsia Backtrace not symbolized, trace different line alignment
 
 use std::env;
 
diff --git a/src/test/ui/std-backtrace.rs b/src/test/ui/std-backtrace.rs
index 3f8306baf8a..59574b471dd 100644
--- a/src/test/ui/std-backtrace.rs
+++ b/src/test/ui/std-backtrace.rs
@@ -4,6 +4,7 @@
 // ignore-openbsd no support for libbacktrace without filename
 // ignore-sgx no processes
 // ignore-msvc see #62897 and `backtrace-debuginfo.rs` test
+// ignore-fuchsia Backtraces not symbolized
 // compile-flags:-g
 // compile-flags:-Cstrip=none
 
diff --git a/src/test/ui/suggestions/issue-101984.rs b/src/test/ui/suggestions/issue-101984.rs
new file mode 100644
index 00000000000..5f7ecb77e0e
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101984.rs
@@ -0,0 +1,27 @@
+use std::marker::PhantomData;
+
+type Component = fn(&());
+
+struct Wrapper {
+    router: Router<(Component, Box<Self>)>,
+}
+
+struct Match<C>(PhantomData<C>);
+
+struct Router<T>(PhantomData<T>);
+
+impl<T> Router<T> {
+    pub fn at(&self) -> Result<Match<&T>, ()> {
+        todo!()
+    }
+}
+
+impl Wrapper {
+    fn at(&self, path: &str) -> Result<(Component, Box<Self>), ()> {
+        let (cmp, router) = self.router.at()?;
+        //~^ ERROR mismatched types
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/suggestions/issue-101984.stderr b/src/test/ui/suggestions/issue-101984.stderr
new file mode 100644
index 00000000000..c744c62d11f
--- /dev/null
+++ b/src/test/ui/suggestions/issue-101984.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-101984.rs:21:13
+   |
+LL |         let (cmp, router) = self.router.at()?;
+   |             ^^^^^^^^^^^^^   ----------------- this expression has type `Match<&(for<'r> fn(&'r ()), Box<Wrapper>)>`
+   |             |
+   |             expected struct `Match`, found tuple
+   |
+   = note: expected struct `Match<&(for<'r> fn(&'r ()), Box<Wrapper>)>`
+               found tuple `(_, _)`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.