From a860a720baa508aa28d44f4d277814a086d6bd9d Mon Sep 17 00:00:00 2001 From: yukang Date: Mon, 20 Mar 2023 22:48:26 +0800 Subject: [PATCH 01/10] Fix issue when there are multiple candidates for edit_distance_with_substrings --- compiler/rustc_span/src/edit_distance.rs | 24 ++++++++++++++++++++---- tests/ui/suggestions/issue-109291.rs | 4 ++++ tests/ui/suggestions/issue-109291.stderr | 12 ++++++++++++ 3 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 tests/ui/suggestions/issue-109291.rs create mode 100644 tests/ui/suggestions/issue-109291.stderr diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 89f0386e3e97f..40d36578350ae 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -174,10 +174,10 @@ pub fn find_best_match_for_name( fn find_best_match_for_name_impl( use_substring_score: bool, candidates: &[Symbol], - lookup: Symbol, + lookup_symbol: Symbol, dist: Option, ) -> Option { - let lookup = lookup.as_str(); + let lookup = lookup_symbol.as_str(); let lookup_uppercase = lookup.to_uppercase(); // Priority of matches: @@ -190,6 +190,7 @@ fn find_best_match_for_name_impl( let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); let mut best = None; + let mut next_candidates = vec![]; for c in candidates { match if use_substring_score { edit_distance_with_substrings(lookup, c.as_str(), dist) @@ -198,12 +199,27 @@ fn find_best_match_for_name_impl( } { Some(0) => return Some(*c), Some(d) => { - dist = d - 1; - best = Some(*c); + if use_substring_score { + dist = d; + next_candidates.push(*c); + best = Some(*c); + } else { + dist = d - 1; + best = Some(*c); + } } None => {} } } + + if next_candidates.len() > 1 { + best = find_best_match_for_name_impl( + false, + &next_candidates, + lookup_symbol, + Some(lookup.len()), + ); + } if best.is_some() { return best; } diff --git a/tests/ui/suggestions/issue-109291.rs b/tests/ui/suggestions/issue-109291.rs new file mode 100644 index 0000000000000..1947b16a32e6e --- /dev/null +++ b/tests/ui/suggestions/issue-109291.rs @@ -0,0 +1,4 @@ +fn main() { + println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); + //~^ ERROR no function or associated item name +} diff --git a/tests/ui/suggestions/issue-109291.stderr b/tests/ui/suggestions/issue-109291.stderr new file mode 100644 index 0000000000000..4ef5948d9bf2b --- /dev/null +++ b/tests/ui/suggestions/issue-109291.stderr @@ -0,0 +1,12 @@ +error[E0599]: no function or associated item named `forced_capture` found for struct `Backtrace` in the current scope + --> $DIR/issue-109291.rs:2:65 + | +LL | println!("Custom backtrace: {}", std::backtrace::Backtrace::forced_capture()); + | ^^^^^^^^^^^^^^ + | | + | function or associated item not found in `Backtrace` + | help: there is an associated function with a similar name: `force_capture` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. From 7b4f436a30f00c8b8bf533b92592385cba2ea5f1 Mon Sep 17 00:00:00 2001 From: yukang Date: Sun, 26 Mar 2023 12:03:25 +0800 Subject: [PATCH 02/10] add comments and cleanup --- compiler/rustc_span/src/edit_distance.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs index 40d36578350ae..19c4aae97efeb 100644 --- a/compiler/rustc_span/src/edit_distance.rs +++ b/compiler/rustc_span/src/edit_distance.rs @@ -190,6 +190,7 @@ fn find_best_match_for_name_impl( let mut dist = dist.unwrap_or_else(|| cmp::max(lookup.len(), 3) / 3); let mut best = None; + // store the candidates with the same distance, only for `use_substring_score` current. let mut next_candidates = vec![]; for c in candidates { match if use_substring_score { @@ -200,19 +201,25 @@ fn find_best_match_for_name_impl( Some(0) => return Some(*c), Some(d) => { if use_substring_score { - dist = d; + if d < dist { + dist = d; + next_candidates.clear(); + } else { + // `d == dist` here, we need to store the candidates with the same distance + // so we won't decrease the distance in the next loop. + } next_candidates.push(*c); - best = Some(*c); } else { dist = d - 1; - best = Some(*c); } + best = Some(*c); } None => {} } } if next_candidates.len() > 1 { + debug_assert!(use_substring_score); best = find_best_match_for_name_impl( false, &next_candidates, From 390246c8e11a28f2087ac25cc419300f03bde693 Mon Sep 17 00:00:00 2001 From: Boxy Date: Sun, 26 Feb 2023 20:49:08 +0000 Subject: [PATCH 03/10] use `ObligationCtxt` not `QueryNormalizer` --- .../src/traits/query/normalize.rs | 12 ++--- src/librustdoc/clean/mod.rs | 50 ++++++++++++++----- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index a986a9b6a71b1..af6c4049029a6 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -284,14 +284,10 @@ impl<'cx, 'tcx> FallibleTypeFolder> for QueryNormalizer<'cx, 'tcx> let result = tcx.normalize_projection_ty(c_data)?; // We don't expect ambiguity. if result.is_ambiguous() { - // Rustdoc normalizes possibly not well-formed types, so only - // treat this as a bug if we're not in rustdoc. - if !tcx.sess.opts.actually_rustdoc { - tcx.sess.delay_span_bug( - DUMMY_SP, - format!("unexpected ambiguity: {:?} {:?}", c_data, result), - ); - } + tcx.sess.delay_span_bug( + DUMMY_SP, + format!("unexpected ambiguity: {:?} {:?}", c_data, result), + ); return Err(NoSolution); } let InferOk { value: result, obligations } = diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2d247bd537bdf..191f89ebe0583 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1666,22 +1666,46 @@ fn normalize<'tcx>( } use crate::rustc_trait_selection::infer::TyCtxtInferExt; - use crate::rustc_trait_selection::traits::query::normalize::QueryNormalizeExt; + use crate::rustc_trait_selection::traits::ObligationCtxt; use rustc_middle::traits::ObligationCause; - // Try to normalize `::T` to a type + assert!( + !ty.has_non_region_infer(), + "`ty`: {:?} has pre existing infer vars before `InferCtxt` creation", + ty + ); + let infcx = cx.tcx.infer_ctxt().build(); - let normalized = infcx - .at(&ObligationCause::dummy(), cx.param_env) - .query_normalize(ty) - .map(|resolved| infcx.resolve_vars_if_possible(resolved.value)); - match normalized { - Ok(normalized_value) => { - debug!("normalized {:?} to {:?}", ty, normalized_value); - Some(normalized_value) - } - Err(err) => { - debug!("failed to normalize {:?}: {:?}", ty, err); + // use an `ObligationCtxt` as it has a nice API for dealing with returned obligations from normalization + // and does not expect us to be inside of typeck. It also does not ICE when the projection could not be + // normalized like some other normalization routines (`QueryNormalizer`, `normalize_erasing_regions`, etc) + let ocx = ObligationCtxt::new(&infcx); + + // Try to normalize `::T` to a type + let normalized = ocx.normalize(&ObligationCause::dummy(), cx.param_env, ty); + // We have to ensure that we deal with nested obligations from attempting to normalize as `ty` + // normalizing to `normalized` is only the case if the nested obligations hold. + let errs = ocx.select_all_or_error(); + // Evaluating nested obligations might constrain infer vars that were created during normalization + // so we should resolve any infer vars in `normalized` to their new values. + let normalized = infcx.resolve_vars_if_possible(normalized); + + match errs.as_slice() { + [] if normalized == ty => { + debug!("normalizing {:?} did not make progress", ty); + None + } + [] => { + debug!("normalized {:?} to {:?}", ty, normalized); + + assert!( + !normalized.has_non_region_infer(), + "`normalized` has infer vars which would escape the `InferCtxt` they were created in" + ); + Some(normalized) + } + errs => { + debug!("failed to normalize {:?}: {:?}", ty, errs); None } } From d0c308c6a955b98c01e79e219abc017ba013f56f Mon Sep 17 00:00:00 2001 From: Boxy Date: Thu, 30 Mar 2023 12:41:55 +0100 Subject: [PATCH 04/10] `{ty:?}` is weird syntax Co-authored-by: Oli Scherer --- src/librustdoc/clean/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 191f89ebe0583..fd5f533c3a1e6 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1671,8 +1671,7 @@ fn normalize<'tcx>( assert!( !ty.has_non_region_infer(), - "`ty`: {:?} has pre existing infer vars before `InferCtxt` creation", - ty + "`ty`: {ty:?} has pre existing infer vars before `InferCtxt` creation", ); let infcx = cx.tcx.infer_ctxt().build(); From 4a4fc3bb5b1efe6857cf5d6c0b554ff36b966996 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Thu, 30 Mar 2023 03:51:27 +0000 Subject: [PATCH 05/10] Implement support for GeneratorWitnessMIR in new solver --- .../solve/trait_goals/structural_traits.rs | 49 +++++++++++++++++-- .../auto-with-drop_tracking_mir.fail.stderr | 18 +++++++ .../new-solver/auto-with-drop_tracking_mir.rs | 26 ++++++++++ 3 files changed, 90 insertions(+), 3 deletions(-) create mode 100644 tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr create mode 100644 tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs index 9817186b874cc..a691b008e9d78 100644 --- a/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs +++ b/compiler/rustc_trait_selection/src/solve/trait_goals/structural_traits.rs @@ -1,7 +1,9 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::{def_id::DefId, Movability, Mutability}; use rustc_infer::traits::query::NoSolution; -use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable}; +use rustc_middle::ty::{ + self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt, +}; use crate::solve::EvalCtxt; @@ -60,7 +62,16 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()), - ty::GeneratorWitnessMIR(..) => todo!(), + ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx + .tcx() + .generator_hidden_types(def_id) + .map(|bty| { + ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars( + tcx, + bty.subst(tcx, substs), + )) + }) + .collect()), // For `PhantomData`, we pass `T`. ty::Adt(def, substs) if def.is_phantom_data() => Ok(vec![substs.type_at(0)]), @@ -76,6 +87,29 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( } } +fn replace_erased_lifetimes_with_bound_vars<'tcx>( + tcx: TyCtxt<'tcx>, + ty: Ty<'tcx>, +) -> ty::Binder<'tcx, Ty<'tcx>> { + debug_assert!(!ty.has_late_bound_regions()); + let mut counter = 0; + let ty = tcx.fold_regions(ty, |mut r, current_depth| { + if let ty::ReErased = r.kind() { + let br = ty::BoundRegion { + var: ty::BoundVar::from_u32(counter), + kind: ty::BrAnon(counter, None), + }; + counter += 1; + r = tcx.mk_re_late_bound(current_depth, br); + } + r + }); + let bound_vars = tcx.mk_bound_variable_kinds_from_iter( + (0..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))), + ); + ty::Binder::bind_with_vars(ty, bound_vars) +} + pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>( ecx: &EvalCtxt<'_, 'tcx>, ty: Ty<'tcx>, @@ -178,7 +212,16 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()), - ty::GeneratorWitnessMIR(..) => todo!(), + ty::GeneratorWitnessMIR(def_id, substs) => Ok(ecx + .tcx() + .generator_hidden_types(def_id) + .map(|bty| { + ecx.instantiate_binder_with_placeholders(replace_erased_lifetimes_with_bound_vars( + ecx.tcx(), + bty.subst(ecx.tcx(), substs), + )) + }) + .collect()), } } diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr new file mode 100644 index 0000000000000..6a926534e079b --- /dev/null +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.fail.stderr @@ -0,0 +1,18 @@ +error[E0277]: `impl Future` cannot be sent between threads safely + --> $DIR/auto-with-drop_tracking_mir.rs:24:13 + | +LL | is_send(foo()); + | ------- ^^^^^ `impl Future` cannot be sent between threads safely + | | + | required by a bound introduced by this call + | + = help: the trait `Send` is not implemented for `impl Future` +note: required by a bound in `is_send` + --> $DIR/auto-with-drop_tracking_mir.rs:23:24 + | +LL | fn is_send(_: impl Send) {} + | ^^^^ required by this bound in `is_send` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs new file mode 100644 index 0000000000000..a5db7c4636b31 --- /dev/null +++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs @@ -0,0 +1,26 @@ +// compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir +// edition: 2021 +// revisions: pass fail +//[pass] check-pass + +#![feature(negative_impls)] + +struct NotSync; +impl !Sync for NotSync {} + +async fn foo() { + #[cfg(pass)] + let x = &(); + #[cfg(fail)] + let x = &NotSync; + bar().await; + drop(x); +} + +async fn bar() {} + +fn main() { + fn is_send(_: impl Send) {} + is_send(foo()); + //[fail]~^ ERROR `impl Future` cannot be sent between threads safely +} From 279f35ce50a7d8b0232a9fd994598ad786470d3f Mon Sep 17 00:00:00 2001 From: Konrad Borowski Date: Wed, 5 Apr 2023 20:58:21 +0200 Subject: [PATCH 06/10] Derive String's PartialEq implementation --- library/alloc/src/string.rs | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs index c7e7ed3e95e02..c1cd3c74ab676 100644 --- a/library/alloc/src/string.rs +++ b/library/alloc/src/string.rs @@ -359,7 +359,7 @@ use crate::vec::Vec; /// [Deref]: core::ops::Deref "ops::Deref" /// [`Deref`]: core::ops::Deref "ops::Deref" /// [`as_str()`]: String::as_str -#[derive(PartialOrd, Eq, Ord)] +#[derive(PartialEq, PartialOrd, Eq, Ord)] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), lang = "String")] pub struct String { @@ -2207,14 +2207,6 @@ impl<'a, 'b> Pattern<'a> for &'b String { } } -#[stable(feature = "rust1", since = "1.0.0")] -impl PartialEq for String { - #[inline] - fn eq(&self, other: &String) -> bool { - PartialEq::eq(&self[..], &other[..]) - } -} - macro_rules! impl_eq { ($lhs:ty, $rhs: ty) => { #[stable(feature = "rust1", since = "1.0.0")] From e9daab25deb3bcfb98716ccd45d02674e0556275 Mon Sep 17 00:00:00 2001 From: Michael Howell Date: Wed, 5 Apr 2023 09:11:10 -0700 Subject: [PATCH 07/10] rustdoc: avoid including line numbers in Google SERP snippets --- src/librustdoc/html/static/css/rustdoc.css | 14 +++++++------- src/librustdoc/html/templates/source.html | 6 ++++-- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index 726394d8348e7..27169c60b1f1f 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -348,7 +348,7 @@ pre.item-decl { .source .content pre { padding: 20px; } -.rustdoc.source .example-wrap > pre.src-line-numbers { +.rustdoc.source .example-wrap pre.src-line-numbers { padding: 20px 0 20px 4px; } @@ -533,17 +533,17 @@ ul.block, .block li { margin-bottom: 0px; } -.rustdoc .example-wrap > pre { +.rustdoc .example-wrap pre { margin: 0; flex-grow: 1; } -.rustdoc:not(.source) .example-wrap > pre { +.rustdoc:not(.source) .example-wrap pre { overflow: auto hidden; } -.rustdoc .example-wrap > pre.example-line-numbers, -.rustdoc .example-wrap > pre.src-line-numbers { +.rustdoc .example-wrap pre.example-line-numbers, +.rustdoc .example-wrap pre.src-line-numbers { flex-grow: 0; min-width: fit-content; /* prevent collapsing into nothing in truncated scraped examples */ overflow: initial; @@ -554,7 +554,7 @@ ul.block, .block li { color: var(--src-line-numbers-span-color); } -.rustdoc .example-wrap > pre.src-line-numbers { +.rustdoc .example-wrap pre.src-line-numbers { padding: 14px 0; } .src-line-numbers a, .src-line-numbers span { @@ -702,7 +702,7 @@ h2.small-section-header > .anchor { } .main-heading a:hover, -.example-wrap > .rust a:hover, +.example-wrap .rust a:hover, .all-items a:hover, .docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover, .docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover, diff --git a/src/librustdoc/html/templates/source.html b/src/librustdoc/html/templates/source.html index a224ff12f448e..42d01277db2c2 100644 --- a/src/librustdoc/html/templates/source.html +++ b/src/librustdoc/html/templates/source.html @@ -1,5 +1,7 @@
{# #} -
+    {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
+       Do not show "1 2 3 4 5 ..." in web search results. #}
+    
         {% for line in lines.clone() %}
             {% if embedded %}
                 {{line|safe}}
@@ -7,7 +9,7 @@
                 {{line|safe}}
             {%~ endif %}
         {% endfor %}
-    
{# #} +
{# #}
 {# #}
         
             {% if needs_expansion %}

From 4fc3c6b07a5aff0bb3da87496daf825b128d6e08 Mon Sep 17 00:00:00 2001
From: yukang 
Date: Thu, 6 Apr 2023 06:51:49 +0800
Subject: [PATCH 08/10] add comment

---
 compiler/rustc_span/src/edit_distance.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/compiler/rustc_span/src/edit_distance.rs b/compiler/rustc_span/src/edit_distance.rs
index 19c4aae97efeb..9fe9e3a7a5fd2 100644
--- a/compiler/rustc_span/src/edit_distance.rs
+++ b/compiler/rustc_span/src/edit_distance.rs
@@ -218,6 +218,9 @@ fn find_best_match_for_name_impl(
         }
     }
 
+    // We have a tie among several candidates, try to select the best among them ignoring substrings.
+    // For example, the candidates list `force_capture`, `capture`, and user inputed `forced_capture`,
+    // we select `force_capture` with a extra round of edit distance calculation.
     if next_candidates.len() > 1 {
         debug_assert!(use_substring_score);
         best = find_best_match_for_name_impl(

From 5cb23e4a439df21e90d5a4789b5d61b2586ee2d2 Mon Sep 17 00:00:00 2001
From: Scott McMurray 
Date: Wed, 5 Apr 2023 14:46:09 -0700
Subject: [PATCH 09/10] Remove f32 & f64 from MemDecoder/MemEncoder

---
 compiler/rustc_metadata/src/rmeta/encoder.rs  |  2 --
 compiler/rustc_middle/src/ty/codec.rs         |  2 --
 .../rustc_query_impl/src/on_disk_cache.rs     |  2 --
 compiler/rustc_serialize/src/opaque.rs        | 36 -------------------
 compiler/rustc_serialize/src/serialize.rs     | 16 +++++----
 compiler/rustc_serialize/tests/opaque.rs      | 32 +++--------------
 6 files changed, 14 insertions(+), 76 deletions(-)

diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 2652a4280d373..5a30371a8456e 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -112,8 +112,6 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
         emit_i8(i8);
 
         emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
         emit_char(char);
         emit_str(&str);
         emit_raw_bytes(&[u8]);
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 3ce80e06ad9ef..8ef4a46a733aa 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -511,8 +511,6 @@ macro_rules! implement_ty_decoder {
                     read_isize -> isize;
 
                     read_bool -> bool;
-                    read_f64 -> f64;
-                    read_f32 -> f32;
                     read_char -> char;
                     read_str -> &str;
                 }
diff --git a/compiler/rustc_query_impl/src/on_disk_cache.rs b/compiler/rustc_query_impl/src/on_disk_cache.rs
index 35b7e5919e42a..9aa8231dcdaeb 100644
--- a/compiler/rustc_query_impl/src/on_disk_cache.rs
+++ b/compiler/rustc_query_impl/src/on_disk_cache.rs
@@ -1046,8 +1046,6 @@ impl<'a, 'tcx> Encoder for CacheEncoder<'a, 'tcx> {
         emit_i8(i8);
 
         emit_bool(bool);
-        emit_f64(f64);
-        emit_f32(f32);
         emit_char(char);
         emit_str(&str);
         emit_raw_bytes(&[u8]);
diff --git a/compiler/rustc_serialize/src/opaque.rs b/compiler/rustc_serialize/src/opaque.rs
index 0e0ebc79eb2e3..53e5c89673652 100644
--- a/compiler/rustc_serialize/src/opaque.rs
+++ b/compiler/rustc_serialize/src/opaque.rs
@@ -122,18 +122,6 @@ impl Encoder for MemEncoder {
         self.emit_u8(if v { 1 } else { 0 });
     }
 
-    #[inline]
-    fn emit_f64(&mut self, v: f64) {
-        let as_u64: u64 = v.to_bits();
-        self.emit_u64(as_u64);
-    }
-
-    #[inline]
-    fn emit_f32(&mut self, v: f32) {
-        let as_u32: u32 = v.to_bits();
-        self.emit_u32(as_u32);
-    }
-
     #[inline]
     fn emit_char(&mut self, v: char) {
         self.emit_u32(v as u32);
@@ -500,18 +488,6 @@ impl Encoder for FileEncoder {
         self.emit_u8(if v { 1 } else { 0 });
     }
 
-    #[inline]
-    fn emit_f64(&mut self, v: f64) {
-        let as_u64: u64 = v.to_bits();
-        self.emit_u64(as_u64);
-    }
-
-    #[inline]
-    fn emit_f32(&mut self, v: f32) {
-        let as_u32: u32 = v.to_bits();
-        self.emit_u32(as_u32);
-    }
-
     #[inline]
     fn emit_char(&mut self, v: char) {
         self.emit_u32(v as u32);
@@ -642,18 +618,6 @@ impl<'a> Decoder for MemDecoder<'a> {
         value != 0
     }
 
-    #[inline]
-    fn read_f64(&mut self) -> f64 {
-        let bits = self.read_u64();
-        f64::from_bits(bits)
-    }
-
-    #[inline]
-    fn read_f32(&mut self) -> f32 {
-        let bits = self.read_u32();
-        f32::from_bits(bits)
-    }
-
     #[inline]
     fn read_char(&mut self) -> char {
         let bits = self.read_u32();
diff --git a/compiler/rustc_serialize/src/serialize.rs b/compiler/rustc_serialize/src/serialize.rs
index 567fe06109b78..527abc2372715 100644
--- a/compiler/rustc_serialize/src/serialize.rs
+++ b/compiler/rustc_serialize/src/serialize.rs
@@ -22,6 +22,11 @@ use std::sync::Arc;
 /// be processed or ignored, whichever is appropriate. Then they should provide
 /// a `finish` method that finishes up encoding. If the encoder is fallible,
 /// `finish` should return a `Result` that indicates success or failure.
+///
+/// This current does not support `f32` nor `f64`, as they're not needed in any
+/// serialized data structures. That could be changed, but consider whether it
+/// really makes sense to store floating-point values at all.
+/// (If you need it, revert .)
 pub trait Encoder {
     // Primitive types:
     fn emit_usize(&mut self, v: usize);
@@ -37,8 +42,6 @@ pub trait Encoder {
     fn emit_i16(&mut self, v: i16);
     fn emit_i8(&mut self, v: i8);
     fn emit_bool(&mut self, v: bool);
-    fn emit_f64(&mut self, v: f64);
-    fn emit_f32(&mut self, v: f32);
     fn emit_char(&mut self, v: char);
     fn emit_str(&mut self, v: &str);
     fn emit_raw_bytes(&mut self, s: &[u8]);
@@ -58,6 +61,11 @@ pub trait Encoder {
 // top-level invocation would also just panic on failure. Switching to
 // infallibility made things faster and lots of code a little simpler and more
 // concise.
+///
+/// This current does not support `f32` nor `f64`, as they're not needed in any
+/// serialized data structures. That could be changed, but consider whether it
+/// really makes sense to store floating-point values at all.
+/// (If you need it, revert .)
 pub trait Decoder {
     // Primitive types:
     fn read_usize(&mut self) -> usize;
@@ -73,8 +81,6 @@ pub trait Decoder {
     fn read_i16(&mut self) -> i16;
     fn read_i8(&mut self) -> i8;
     fn read_bool(&mut self) -> bool;
-    fn read_f64(&mut self) -> f64;
-    fn read_f32(&mut self) -> f32;
     fn read_char(&mut self) -> char;
     fn read_str(&mut self) -> &str;
     fn read_raw_bytes(&mut self, len: usize) -> &[u8];
@@ -143,8 +149,6 @@ direct_serialize_impls! {
     i64 emit_i64 read_i64,
     i128 emit_i128 read_i128,
 
-    f32 emit_f32 read_f32,
-    f64 emit_f64 read_f64,
     bool emit_bool read_bool,
     char emit_char read_char
 }
diff --git a/compiler/rustc_serialize/tests/opaque.rs b/compiler/rustc_serialize/tests/opaque.rs
index 3a695d0714ee1..5e7dd18aa8408 100644
--- a/compiler/rustc_serialize/tests/opaque.rs
+++ b/compiler/rustc_serialize/tests/opaque.rs
@@ -22,8 +22,6 @@ struct Struct {
 
     l: char,
     m: String,
-    n: f32,
-    o: f64,
     p: bool,
     q: Option,
 }
@@ -119,24 +117,6 @@ fn test_bool() {
     check_round_trip(vec![false, true, true, false, false]);
 }
 
-#[test]
-fn test_f32() {
-    let mut vec = vec![];
-    for i in -100..100 {
-        vec.push((i as f32) / 3.0);
-    }
-    check_round_trip(vec);
-}
-
-#[test]
-fn test_f64() {
-    let mut vec = vec![];
-    for i in -100..100 {
-        vec.push((i as f64) / 3.0);
-    }
-    check_round_trip(vec);
-}
-
 #[test]
 fn test_char() {
     let vec = vec!['a', 'b', 'c', 'd', 'A', 'X', ' ', '#', 'Ö', 'Ä', 'µ', '€'];
@@ -200,8 +180,6 @@ fn test_struct() {
 
         l: 'x',
         m: "abc".to_string(),
-        n: 20.5,
-        o: 21.5,
         p: false,
         q: None,
     }]);
@@ -222,8 +200,6 @@ fn test_struct() {
 
         l: 'y',
         m: "def".to_string(),
-        n: -20.5,
-        o: -21.5,
         p: true,
         q: Some(1234567),
     }]);
@@ -232,7 +208,7 @@ fn test_struct() {
 #[derive(PartialEq, Clone, Debug, Encodable, Decodable)]
 enum Enum {
     Variant1,
-    Variant2(usize, f32),
+    Variant2(usize, u32),
     Variant3 { a: i32, b: char, c: bool },
 }
 
@@ -240,7 +216,7 @@ enum Enum {
 fn test_enum() {
     check_round_trip(vec![
         Enum::Variant1,
-        Enum::Variant2(1, 2.5),
+        Enum::Variant2(1, 25),
         Enum::Variant3 { a: 3, b: 'b', c: false },
         Enum::Variant3 { a: -4, b: 'f', c: true },
     ]);
@@ -269,8 +245,8 @@ fn test_hash_map() {
 
 #[test]
 fn test_tuples() {
-    check_round_trip(vec![('x', (), false, 0.5f32)]);
-    check_round_trip(vec![(9i8, 10u16, 1.5f64)]);
+    check_round_trip(vec![('x', (), false, 5u32)]);
+    check_round_trip(vec![(9i8, 10u16, 15i64)]);
     check_round_trip(vec![(-12i16, 11u8, 12usize)]);
     check_round_trip(vec![(1234567isize, 100000000000000u64, 99999999999999i64)]);
     check_round_trip(vec![(String::new(), "some string".to_string())]);

From 38b1741276f5b2eca344fd2a2fd4ea4e532d316d Mon Sep 17 00:00:00 2001
From: ozkanonur 
Date: Thu, 6 Apr 2023 12:44:21 +0300
Subject: [PATCH 10/10] improve/extend `detect_src_and_out` test

Signed-off-by: ozkanonur 
---
 src/bootstrap/config/tests.rs | 61 +++++++++++++++++++++++------------
 1 file changed, 40 insertions(+), 21 deletions(-)

diff --git a/src/bootstrap/config/tests.rs b/src/bootstrap/config/tests.rs
index 16dc8c63abc96..0667ad280d482 100644
--- a/src/bootstrap/config/tests.rs
+++ b/src/bootstrap/config/tests.rs
@@ -33,35 +33,54 @@ fn download_ci_llvm() {
     ));
 }
 
+// FIXME(ozkanonur): extend scope of the test
+// refs:
+//   - https://github.com/rust-lang/rust/issues/109120
+//   - https://github.com/rust-lang/rust/pull/109162#issuecomment-1496782487
 #[test]
 fn detect_src_and_out() {
-    let cfg = parse("");
+    fn test(cfg: Config, build_dir: Option<&str>) {
+        // This will bring absolute form of `src/bootstrap` path
+        let current_dir = std::env::current_dir().unwrap();
 
-    // This will bring absolute form of `src/bootstrap` path
-    let current_dir = std::env::current_dir().unwrap();
+        // get `src` by moving into project root path
+        let expected_src = current_dir.ancestors().nth(2).unwrap();
+        assert_eq!(&cfg.src, expected_src);
 
-    // get `src` by moving into project root path
-    let expected_src = current_dir.ancestors().nth(2).unwrap();
+        // Sanity check for `src`
+        let manifest_dir = Path::new(env!("CARGO_MANIFEST_DIR"));
+        let expected_src = manifest_dir.ancestors().nth(2).unwrap();
+        assert_eq!(&cfg.src, expected_src);
 
-    assert_eq!(&cfg.src, expected_src);
+        // test if build-dir was manually given in config.toml
+        if let Some(custom_build_dir) = build_dir {
+            assert_eq!(&cfg.out, Path::new(custom_build_dir));
+        }
+        // test the native bootstrap way
+        else {
+            // This should bring output path of bootstrap in absolute form
+            let cargo_target_dir = env::var_os("CARGO_TARGET_DIR").expect(
+                "CARGO_TARGET_DIR must been provided for the test environment from bootstrap",
+            );
 
-    // This should bring output path of bootstrap in absolute form
-    let cargo_target_dir = env::var_os("CARGO_TARGET_DIR")
-        .expect("CARGO_TARGET_DIR must been provided for the test environment from bootstrap");
+            // Move to `build` from `build/bootstrap`
+            let expected_out = Path::new(&cargo_target_dir).parent().unwrap();
+            assert_eq!(&cfg.out, expected_out);
 
-    // Move to `build` from `build/bootstrap`
-    let expected_out = Path::new(&cargo_target_dir).parent().unwrap();
-    assert_eq!(&cfg.out, expected_out);
+            let args: Vec = env::args().collect();
 
-    let args: Vec = env::args().collect();
+            // Another test for `out` as a sanity check
+            //
+            // This will bring something similar to:
+            //     `{build-dir}/bootstrap/debug/deps/bootstrap-c7ee91d5661e2804`
+            // `{build-dir}` can be anywhere, not just in the rust project directory.
+            let dep = Path::new(args.first().unwrap());
+            let expected_out = dep.ancestors().nth(4).unwrap();
 
-    // Another test for `out` as a sanity check
-    //
-    // This will bring something similar to:
-    //     `{config_toml_place}/build/bootstrap/debug/deps/bootstrap-c7ee91d5661e2804`
-    // `{config_toml_place}` can be anywhere, not just in the rust project directory.
-    let dep = Path::new(args.first().unwrap());
-    let expected_out = dep.ancestors().nth(4).unwrap();
+            assert_eq!(&cfg.out, expected_out);
+        }
+    }
 
-    assert_eq!(&cfg.out, expected_out);
+    test(parse(""), None);
+    test(parse("build.build-dir = \"/tmp\""), Some("/tmp"));
 }