diff options
| author | bors <bors@rust-lang.org> | 2025-03-24 19:43:42 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-03-24 19:43:42 +0000 |
| commit | f8c27dfe1a2e7fb538fd91dad53de06992c7c967 (patch) | |
| tree | c453df3f38612e8b1cbd7714e78dffaadba831ff /compiler | |
| parent | 4510e86a41388733675465a8647d4235f3bf2023 (diff) | |
| parent | 4202bf96698125785719a061dec561a8ab70ba9c (diff) | |
| download | rust-f8c27dfe1a2e7fb538fd91dad53de06992c7c967.tar.gz rust-f8c27dfe1a2e7fb538fd91dad53de06992c7c967.zip | |
Auto merge of #138901 - matthiaskrgr:rollup-qbbanhr, r=matthiaskrgr
Rollup of 7 pull requests Successful merges: - #138662 (Implement some basics in UEFI fs) - #138800 (remove remnants of const_box feature) - #138821 (match lowering cleanup: remove unused unsizing logic from `non_scalar_compare`) - #138864 (Rework `--print` options documentation) - #138868 (Add do_not_recommend typo help) - #138882 (`with_scope` is only ever used for ast modules) - #138894 (Update books) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
| -rw-r--r-- | compiler/rustc_middle/src/thir.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/builder/matches/mod.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_mir_build/src/builder/matches/test.rs | 108 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 25 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/macros.rs | 14 |
5 files changed, 42 insertions, 115 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs index bbcd509c558..6783bbf8bf4 100644 --- a/compiler/rustc_middle/src/thir.rs +++ b/compiler/rustc_middle/src/thir.rs @@ -800,9 +800,9 @@ pub enum PatKind<'tcx> { }, /// One of the following: - /// * `&str`/`&[u8]` (represented as a valtree), which will be handled as a string/slice pattern - /// and thus exhaustiveness checking will detect if you use the same string/slice twice in - /// different patterns. + /// * `&str` (represented as a valtree), which will be handled as a string pattern and thus + /// exhaustiveness checking will detect if you use the same string twice in different + /// patterns. /// * integer, bool, char or float (represented as a valtree), which will be handled by /// exhaustiveness to cover exactly its own value, similar to `&str`, but these values are /// much simpler. diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs index ea341b604e0..710538ef4b8 100644 --- a/compiler/rustc_mir_build/src/builder/matches/mod.rs +++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs @@ -1326,8 +1326,8 @@ enum TestKind<'tcx> { Eq { value: Const<'tcx>, // Integer types are handled by `SwitchInt`, and constants with ADT - // types are converted back into patterns, so this can only be `&str`, - // `&[T]`, `f32` or `f64`. + // types and `&[T]` types are converted back into patterns, so this can + // only be `&str`, `f32` or `f64`. ty: Ty<'tcx>, }, diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs index e5d61bc9e55..7ef9e48326f 100644 --- a/compiler/rustc_mir_build/src/builder/matches/test.rs +++ b/compiler/rustc_mir_build/src/builder/matches/test.rs @@ -11,7 +11,6 @@ use std::sync::Arc; use rustc_data_structures::fx::FxIndexMap; use rustc_hir::{LangItem, RangeEnd}; use rustc_middle::mir::*; -use rustc_middle::ty::adjustment::PointerCoercion; use rustc_middle::ty::util::IntTypeExt; use rustc_middle::ty::{self, GenericArg, Ty, TyCtxt}; use rustc_middle::{bug, span_bug}; @@ -178,21 +177,30 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { _ => {} } + assert_eq!(expect_ty, ty); if !ty.is_scalar() { // Use `PartialEq::eq` instead of `BinOp::Eq` // (the binop can only handle primitives) - self.non_scalar_compare( + // Make sure that we do *not* call any user-defined code here. + // The only type that can end up here is string literals, which have their + // comparison defined in `core`. + // (Interestingly this means that exhaustiveness analysis relies, for soundness, + // on the `PartialEq` impl for `str` to b correct!) + match *ty.kind() { + ty::Ref(_, deref_ty, _) if deref_ty == self.tcx.types.str_ => {} + _ => { + span_bug!(source_info.span, "invalid type for non-scalar compare: {ty}") + } + }; + self.string_compare( block, success_block, fail_block, source_info, expect, - expect_ty, Operand::Copy(place), - ty, ); } else { - assert_eq!(expect_ty, ty); self.compare( block, success_block, @@ -370,97 +378,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { ); } - /// Compare two values using `<T as std::compare::PartialEq>::eq`. - /// If the values are already references, just call it directly, otherwise - /// take a reference to the values first and then call it. - fn non_scalar_compare( + /// Compare two values of type `&str` using `<str as std::cmp::PartialEq>::eq`. + fn string_compare( &mut self, block: BasicBlock, success_block: BasicBlock, fail_block: BasicBlock, source_info: SourceInfo, - mut expect: Operand<'tcx>, - expect_ty: Ty<'tcx>, - mut val: Operand<'tcx>, - mut ty: Ty<'tcx>, + expect: Operand<'tcx>, + val: Operand<'tcx>, ) { - // If we're using `b"..."` as a pattern, we need to insert an - // unsizing coercion, as the byte string has the type `&[u8; N]`. - // - // We want to do this even when the scrutinee is a reference to an - // array, so we can call `<[u8]>::eq` rather than having to find an - // `<[u8; N]>::eq`. - let unsize = |ty: Ty<'tcx>| match ty.kind() { - ty::Ref(region, rty, _) => match rty.kind() { - ty::Array(inner_ty, n) => Some((region, inner_ty, n)), - _ => None, - }, - _ => None, - }; - let opt_ref_ty = unsize(ty); - let opt_ref_test_ty = unsize(expect_ty); - match (opt_ref_ty, opt_ref_test_ty) { - // nothing to do, neither is an array - (None, None) => {} - (Some((region, elem_ty, _)), _) | (None, Some((region, elem_ty, _))) => { - let tcx = self.tcx; - // make both a slice - ty = Ty::new_imm_ref(tcx, *region, Ty::new_slice(tcx, *elem_ty)); - if opt_ref_ty.is_some() { - let temp = self.temp(ty, source_info.span); - self.cfg.push_assign( - block, - source_info, - temp, - Rvalue::Cast( - CastKind::PointerCoercion( - PointerCoercion::Unsize, - CoercionSource::Implicit, - ), - val, - ty, - ), - ); - val = Operand::Copy(temp); - } - if opt_ref_test_ty.is_some() { - let slice = self.temp(ty, source_info.span); - self.cfg.push_assign( - block, - source_info, - slice, - Rvalue::Cast( - CastKind::PointerCoercion( - PointerCoercion::Unsize, - CoercionSource::Implicit, - ), - expect, - ty, - ), - ); - expect = Operand::Move(slice); - } - } - } - - // Figure out the type on which we are calling `PartialEq`. This involves an extra wrapping - // reference: we can only compare two `&T`, and then compare_ty will be `T`. - // Make sure that we do *not* call any user-defined code here. - // The only types that can end up here are string and byte literals, - // which have their comparison defined in `core`. - // (Interestingly this means that exhaustiveness analysis relies, for soundness, - // on the `PartialEq` impls for `str` and `[u8]` to b correct!) - let compare_ty = match *ty.kind() { - ty::Ref(_, deref_ty, _) - if deref_ty == self.tcx.types.str_ || deref_ty != self.tcx.types.u8 => - { - deref_ty - } - _ => span_bug!(source_info.span, "invalid type for non-scalar compare: {}", ty), - }; - + let str_ty = self.tcx.types.str_; let eq_def_id = self.tcx.require_lang_item(LangItem::PartialEq, Some(source_info.span)); - let method = trait_method(self.tcx, eq_def_id, sym::eq, [compare_ty, compare_ty]); + let method = trait_method(self.tcx, eq_def_id, sym::eq, [str_ty, str_ty]); let bool_ty = self.tcx.types.bool; let eq_result = self.temp(bool_ty, source_info.span); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 6056a69ee71..e04d0083548 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1544,20 +1544,17 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ret } - fn with_scope<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { - if let Some(module) = self.r.get_module(self.r.local_def_id(id).to_def_id()) { - // Move down in the graph. - let orig_module = replace(&mut self.parent_scope.module, module); - self.with_rib(ValueNS, RibKind::Module(module), |this| { - this.with_rib(TypeNS, RibKind::Module(module), |this| { - let ret = f(this); - this.parent_scope.module = orig_module; - ret - }) + fn with_mod_rib<T>(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { + let module = self.r.expect_module(self.r.local_def_id(id).to_def_id()); + // Move down in the graph. + let orig_module = replace(&mut self.parent_scope.module, module); + self.with_rib(ValueNS, RibKind::Module(module), |this| { + this.with_rib(TypeNS, RibKind::Module(module), |this| { + let ret = f(this); + this.parent_scope.module = orig_module; + ret }) - } else { - f(self) - } + }) } fn visit_generic_params(&mut self, params: &'ast [GenericParam], add_self_upper: bool) { @@ -2738,7 +2735,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } ItemKind::Mod(..) => { - self.with_scope(item.id, |this| { + self.with_mod_rib(item.id, |this| { if mod_inner_docs { this.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id)); } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index c4304a7a6df..34441d313f5 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -28,7 +28,7 @@ use rustc_session::lint::builtin::{ UNUSED_MACRO_RULES, UNUSED_MACROS, }; use rustc_session::parse::feature_err; -use rustc_span::edit_distance::edit_distance; +use rustc_span::edit_distance::find_best_match_for_name; use rustc_span::edition::Edition; use rustc_span::hygiene::{self, AstPass, ExpnData, ExpnKind, LocalExpnId, MacroKind}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; @@ -652,13 +652,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if res == Res::NonMacroAttr(NonMacroAttrKind::Tool) && let [namespace, attribute, ..] = &*path.segments && namespace.ident.name == sym::diagnostic - && !(attribute.ident.name == sym::on_unimplemented - || attribute.ident.name == sym::do_not_recommend) + && ![sym::on_unimplemented, sym::do_not_recommend].contains(&attribute.ident.name) { - let distance = - edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5); - - let typo_name = distance.map(|_| sym::on_unimplemented); + let typo_name = find_best_match_for_name( + &[sym::on_unimplemented, sym::do_not_recommend], + attribute.ident.name, + Some(5), + ); self.tcx.sess.psess.buffer_lint( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, |
