From d358ccace43533b8f2c2dcecbca2631df5e5dcb0 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 Feb 2023 00:00:18 +0000 Subject: [PATCH 1/4] Don't intern str --- compiler/rustc_codegen_gcc/src/common.rs | 2 +- compiler/rustc_codegen_llvm/src/common.rs | 2 +- compiler/rustc_const_eval/src/interpret/place.rs | 7 +++---- compiler/rustc_hir_analysis/src/astconv/mod.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 7 ++++++- compiler/rustc_mir_build/src/build/matches/test.rs | 2 +- tests/codegen/function-arguments.rs | 7 +++++++ 7 files changed, 20 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs index c939da9cec3c2..3ac151f81943a 100644 --- a/compiler/rustc_codegen_gcc/src/common.rs +++ b/compiler/rustc_codegen_gcc/src/common.rs @@ -133,7 +133,7 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> { .1; let len = s.len(); let cs = self.const_ptrcast(str_global.get_address(None), - self.type_ptr_to(self.layout_of(self.tcx.types.str_).gcc_type(self, true)), + self.type_ptr_to(self.layout_of(self.tcx.mk_str()).gcc_type(self, true)), ); (cs, self.const_usize(len as u64)) } diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs index edb1c160626ea..3bad85d5e27a2 100644 --- a/compiler/rustc_codegen_llvm/src/common.rs +++ b/compiler/rustc_codegen_llvm/src/common.rs @@ -205,7 +205,7 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> { let len = s.len(); let cs = consts::ptrcast( str_global, - self.type_ptr_to(self.layout_of(self.tcx.types.str_).llvm_type(self)), + self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)), ); (cs, self.const_usize(len as u64)) } diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 038282e2161e6..6f9dcc2fe8e05 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -759,10 +759,9 @@ where let meta = Scalar::from_machine_usize(u64::try_from(str.len()).unwrap(), self); let mplace = MemPlace { ptr: ptr.into(), meta: MemPlaceMeta::Meta(meta) }; - let ty = self.tcx.mk_ref( - self.tcx.lifetimes.re_static, - ty::TypeAndMut { ty: self.tcx.types.str_, mutbl }, - ); + let ty = self + .tcx + .mk_ref(self.tcx.lifetimes.re_static, ty::TypeAndMut { ty: self.tcx.mk_str(), mutbl }); let layout = self.layout_of(ty).unwrap(); Ok(MPlaceTy { mplace, layout, align: layout.align.abi }) } diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs index 75cc7cbaa6053..cf48a04daa28a 100644 --- a/compiler/rustc_hir_analysis/src/astconv/mod.rs +++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs @@ -2819,7 +2819,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { hir::PrimTy::Int(it) => tcx.mk_mach_int(ty::int_ty(it)), hir::PrimTy::Uint(uit) => tcx.mk_mach_uint(ty::uint_ty(uit)), hir::PrimTy::Float(ft) => tcx.mk_mach_float(ty::float_ty(ft)), - hir::PrimTy::Str => tcx.types.str_, + hir::PrimTy::Str => tcx.mk_str(), } } Res::Err => { diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 04537ad635a50..b7566cc46389c 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1665,7 +1665,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_static_str(self) -> Ty<'tcx> { - self.mk_imm_ref(self.lifetimes.re_static, self.types.str_) + self.mk_imm_ref(self.lifetimes.re_static, self.mk_str()) } #[inline] @@ -1897,6 +1897,11 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_ty(Param(ParamTy { index, name })) } + #[inline] + pub fn mk_str(self) -> Ty<'tcx> { + self.mk_ty(Str) + } + pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { match param.kind { GenericParamDefKind::Lifetime => { diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs index ad7a568a23181..6a7a759eb5379 100644 --- a/compiler/rustc_mir_build/src/build/matches/test.rs +++ b/compiler/rustc_mir_build/src/build/matches/test.rs @@ -245,7 +245,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { } let re_erased = tcx.lifetimes.re_erased; let ref_string = self.temp(tcx.mk_imm_ref(re_erased, ty), test.span); - let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.types.str_); + let ref_str_ty = tcx.mk_imm_ref(re_erased, tcx.mk_str()); let ref_str = self.temp(ref_str_ty, test.span); let deref = tcx.require_lang_item(LangItem::Deref, None); let method = trait_method(tcx, deref, sym::deref, [ty]); diff --git a/tests/codegen/function-arguments.rs b/tests/codegen/function-arguments.rs index 96dfde18683e3..b27341e692356 100644 --- a/tests/codegen/function-arguments.rs +++ b/tests/codegen/function-arguments.rs @@ -1,6 +1,7 @@ // compile-flags: -O -C no-prepopulate-passes #![crate_type = "lib"] +#![feature(dyn_star)] use std::mem::MaybeUninit; use std::num::NonZeroU64; @@ -279,3 +280,9 @@ pub fn enum_id_1(x: Option>) -> Option> { pub fn enum_id_2(x: Option) -> Option { x } + +// CHECK: { {{i8\*|ptr}}, {{i8\*|ptr}} } @dyn_star({{i8\*|ptr}} noundef %x.0, {{i8\*|ptr}} noalias noundef readonly align {{.*}} dereferenceable({{.*}}) %x.1) +#[no_mangle] +pub fn dyn_star(x: dyn* Drop) -> dyn* Drop { + x +} From efd02e1323ce8e269cfbfb99eb629211d0c35a3d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 Feb 2023 03:14:33 +0000 Subject: [PATCH 2/4] Make str into a real struct --- .../src/debuginfo/metadata.rs | 3 +- .../rustc_codegen_llvm/src/debuginfo/utils.rs | 2 +- compiler/rustc_codegen_llvm/src/type_of.rs | 2 +- .../src/debuginfo/type_names.rs | 2 +- compiler/rustc_codegen_ssa/src/glue.rs | 2 +- compiler/rustc_codegen_ssa/src/mir/place.rs | 2 +- .../rustc_codegen_ssa/src/traits/type_.rs | 2 +- .../src/const_eval/eval_queries.rs | 2 +- .../rustc_const_eval/src/const_eval/mod.rs | 1 - .../src/const_eval/valtrees.rs | 36 ++++++----- .../src/interpret/eval_context.rs | 16 ++++- .../src/interpret/intrinsics.rs | 1 - .../rustc_const_eval/src/interpret/place.rs | 5 +- .../src/interpret/projection.rs | 5 +- .../src/interpret/validity.rs | 12 +--- .../rustc_const_eval/src/util/type_name.rs | 1 - compiler/rustc_hir/src/lang_items.rs | 1 + .../src/coherence/inherent_impls.rs | 1 - .../src/coherence/orphan.rs | 1 - .../src/variance/constraints.rs | 1 - compiler/rustc_hir_typeck/src/cast.rs | 4 +- compiler/rustc_hir_typeck/src/demand.rs | 4 +- compiler/rustc_hir_typeck/src/expectation.rs | 3 +- compiler/rustc_hir_typeck/src/expr.rs | 2 +- compiler/rustc_hir_typeck/src/method/probe.rs | 1 - .../rustc_hir_typeck/src/method/suggest.rs | 1 - compiler/rustc_hir_typeck/src/op.rs | 13 ++-- compiler/rustc_hir_typeck/src/pat.rs | 2 +- .../src/infer/canonical/canonicalizer.rs | 1 - .../src/infer/outlives/components.rs | 1 - compiler/rustc_lint/src/builtin.rs | 2 +- compiler/rustc_lint/src/non_fmt_panic.rs | 2 +- compiler/rustc_lint/src/types.rs | 13 ++-- compiler/rustc_middle/src/mir/mod.rs | 2 +- compiler/rustc_middle/src/ty/adt.rs | 12 +++- .../rustc_middle/src/ty/consts/valtree.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_middle/src/ty/diagnostics.rs | 7 ++- compiler/rustc_middle/src/ty/error.rs | 2 +- compiler/rustc_middle/src/ty/fast_reject.rs | 5 +- compiler/rustc_middle/src/ty/flags.rs | 1 - compiler/rustc_middle/src/ty/layout.rs | 3 +- compiler/rustc_middle/src/ty/print/mod.rs | 1 - compiler/rustc_middle/src/ty/print/pretty.rs | 6 +- compiler/rustc_middle/src/ty/relate.rs | 1 - .../rustc_middle/src/ty/structural_impls.rs | 2 - compiler/rustc_middle/src/ty/sty.rs | 15 +++-- compiler/rustc_middle/src/ty/util.rs | 14 +++-- compiler/rustc_middle/src/ty/walk.rs | 1 - .../src/build/expr/as_rvalue.rs | 2 +- .../src/thir/pattern/const_to_pat.rs | 2 +- .../src/thir/pattern/deconstruct_pat.rs | 4 +- compiler/rustc_mir_transform/src/add_retag.rs | 1 - compiler/rustc_monomorphize/src/collector.rs | 2 +- compiler/rustc_privacy/src/lib.rs | 1 - .../src/typeid/typeid_itanium_cxx_abi.rs | 3 +- compiler/rustc_symbol_mangling/src/v0.rs | 60 +++++++++---------- .../src/solve/assembly.rs | 2 - .../src/solve/project_goals.rs | 2 +- .../solve/trait_goals/structural_traits.rs | 6 +- .../src/traits/coherence.rs | 1 - .../src/traits/error_reporting/mod.rs | 7 ++- .../src/traits/project.rs | 2 - .../src/traits/query/dropck_outlives.rs | 4 +- .../query/type_op/implied_outlives_bounds.rs | 3 +- .../src/traits/select/candidate_assembly.rs | 2 - .../src/traits/select/confirmation.rs | 1 - .../src/traits/select/mod.rs | 10 +++- .../src/traits/structural_match.rs | 2 +- .../rustc_trait_selection/src/traits/wf.rs | 1 - compiler/rustc_traits/src/chalk/db.rs | 1 - compiler/rustc_traits/src/chalk/lowering.rs | 3 +- compiler/rustc_traits/src/dropck_outlives.rs | 1 - compiler/rustc_ty_utils/src/layout.rs | 10 +--- compiler/rustc_ty_utils/src/ty.rs | 3 +- compiler/rustc_type_ir/src/sty.rs | 16 ++--- library/core/src/str/mod.rs | 9 +++ library/core/src/str/traits.rs | 8 +++ .../src/methods/expect_fun_call.rs | 4 +- .../src/methods/search_is_some.rs | 2 +- .../src/methods/single_char_pattern.rs | 2 +- .../src/methods/string_extend_chars.rs | 2 +- src/tools/clippy/clippy_lints/src/strings.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- .../issue-72590-type-error-sized.stderr | 4 +- .../coherence-negative-impls-copy-bad.stderr | 2 +- .../consts/const-eval/raw-bytes.64bit.stderr | 4 +- tests/ui/consts/const-eval/ub-wide-ptr.stderr | 4 +- ...4637-deprecated-associated-function.stderr | 4 +- tests/ui/kinds-of-primitive-impl.stderr | 17 ++++-- .../ui/pattern/usefulness/issue-30240.stderr | 4 ++ .../ui/print_type_sizes/niche-filling.stdout | 2 + tests/ui/str/str-idx.stderr | 4 +- tests/ui/str/str-mut-idx.stderr | 4 +- tests/ui/suggestions/issue-62843.stderr | 2 +- tests/ui/symbol-names/basic.legacy.stderr | 4 +- .../ui/symbol-names/issue-60925.legacy.stderr | 4 +- .../suggest-deferences/root-obligation.stderr | 2 +- 98 files changed, 240 insertions(+), 231 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs index f73bbf3d22bd7..767e54df62a23 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs @@ -406,7 +406,6 @@ fn build_slice_type_di_node<'ll, 'tcx>( ) -> DINodeCreationResult<'ll> { let element_type = match slice_type.kind() { ty::Slice(element_type) => *element_type, - ty::Str => cx.tcx.types.u8, _ => { bug!( "Only ty::Slice is valid for build_slice_type_di_node(). Found {:?} instead.", @@ -440,7 +439,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D } ty::Tuple(elements) if elements.is_empty() => build_basic_type_di_node(cx, t), ty::Array(..) => build_fixed_size_array_di_node(cx, unique_type_id, t), - ty::Slice(_) | ty::Str => build_slice_type_di_node(cx, t, unique_type_id), + ty::Slice(_) => build_slice_type_di_node(cx, t, unique_type_id), ty::Dynamic(..) => build_dyn_type_di_node(cx, t, unique_type_id), ty::Foreign(..) => build_foreign_type_di_node(cx, t, unique_type_id), ty::RawPtr(ty::TypeAndMut { ty: pointee_type, .. }) | ty::Ref(_, pointee_type, _) => { diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index 5cd0e1cb63ae1..aee515811c932 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs @@ -77,7 +77,7 @@ pub(crate) fn fat_pointer_kind<'ll, 'tcx>( } match *pointee_tail_ty.kind() { - ty::Str | ty::Slice(_) => Some(FatPtrKind::Slice), + ty::Slice(_) => Some(FatPtrKind::Slice), ty::Dynamic(..) => Some(FatPtrKind::Dyn), ty::Foreign(_) => { // Assert that pointers to foreign types really are thin: diff --git a/compiler/rustc_codegen_llvm/src/type_of.rs b/compiler/rustc_codegen_llvm/src/type_of.rs index c73d233b767a4..55db71e5f4911 100644 --- a/compiler/rustc_codegen_llvm/src/type_of.rs +++ b/compiler/rustc_codegen_llvm/src/type_of.rs @@ -42,7 +42,7 @@ fn uncached_llvm_type<'a, 'tcx>( // FIXME(eddyb) producing readable type names for trait objects can result // in problematically distinct types due to HRTB and subtyping (see #47638). // ty::Dynamic(..) | - ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str + ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) // For performance reasons we use names only when emitting LLVM IR. Unless we are on // LLVM < 14, where the use of unnamed types resulted in various issues, e.g., #76213, // #79564, and #79246. diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index b0e007ce0097b..7e10f8e586f6b 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -59,7 +59,7 @@ fn push_debuginfo_type_name<'tcx>( match *t.kind() { ty::Bool => output.push_str("bool"), ty::Char => output.push_str("char"), - ty::Str => { + ty::Adt(def, _) if def.is_str() => { if cpp_like_debuginfo { output.push_str("str$") } else { diff --git a/compiler/rustc_codegen_ssa/src/glue.rs b/compiler/rustc_codegen_ssa/src/glue.rs index 0f6e6032f9bff..3047333ce2e47 100644 --- a/compiler/rustc_codegen_ssa/src/glue.rs +++ b/compiler/rustc_codegen_ssa/src/glue.rs @@ -37,7 +37,7 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>( (size, align) } - ty::Slice(_) | ty::Str => { + ty::Slice(_) => { let unit = layout.field(bx, 0); // The info in this case is the length of the str, so the size is that // times the unit size. diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs index cf02f59f67b97..6b511323404e3 100644 --- a/compiler/rustc_codegen_ssa/src/mir/place.rs +++ b/compiler/rustc_codegen_ssa/src/mir/place.rs @@ -146,7 +146,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> { return simple(); } _ if field.is_sized() => return simple(), - ty::Slice(..) | ty::Str | ty::Foreign(..) => return simple(), + ty::Slice(..) | ty::Foreign(..) => return simple(), ty::Adt(def, _) => { if def.repr().packed() { // FIXME(eddyb) generalize the adjustment when we diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs index 109161ccc8368..b770be6af1bdb 100644 --- a/compiler/rustc_codegen_ssa/src/traits/type_.rs +++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs @@ -91,7 +91,7 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> { let tail = self.tcx().struct_tail_erasing_lifetimes(ty, param_env); match tail.kind() { ty::Foreign(..) => false, - ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, + ty::Slice(..) | ty::Dynamic(..) => true, _ => bug!("unexpected unsized tail: {:?}", tail), } } diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs index b4a49e1df610c..ae1d58ca7d9e1 100644 --- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs @@ -126,7 +126,7 @@ pub(super) fn op_to_const<'tcx>( Abi::ScalarPair(..) => match op.layout.ty.kind() { ty::Ref(_, inner, _) => match *inner.kind() { ty::Slice(elem) => elem == ecx.tcx.types.u8, - ty::Str => true, + ty::Adt(def, _) => def.is_str(), _ => false, }, _ => false, diff --git a/compiler/rustc_const_eval/src/const_eval/mod.rs b/compiler/rustc_const_eval/src/const_eval/mod.rs index 01b2b4b5d9cd3..07cfe64ab46a4 100644 --- a/compiler/rustc_const_eval/src/const_eval/mod.rs +++ b/compiler/rustc_const_eval/src/const_eval/mod.rs @@ -154,7 +154,6 @@ pub(crate) fn deref_mir_constant<'tcx>( MemPlaceMeta::None => mplace.layout.ty, // In case of unsized types, figure out the real type behind. MemPlaceMeta::Meta(scalar) => match mplace.layout.ty.kind() { - ty::Str => bug!("there's no sized equivalent of a `str`"), ty::Slice(elem_ty) => tcx.mk_array(*elem_ty, scalar.to_machine_usize(&tcx).unwrap()), _ => bug!( "type {} should not have metadata, but had {:?}", diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index c52886b77e64b..4f7bb280a0377 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -111,9 +111,15 @@ pub(crate) fn const_to_valtree_inner<'tcx>( const_to_valtree_inner(ecx, &derefd_place, num_nodes) } - ty::Str | ty::Slice(_) | ty::Array(_, _) => { + ty::Slice(_) | ty::Array(_, _) => { slice_branches(ecx, place, num_nodes) } + + // FIXME(str): Do we need this? + ty::Adt(def, _) if def.is_str() => { + slice_branches(ecx, place, num_nodes) + } + // Trait objects are not allowed in type level constants, as we have no concept for // resolving their backing type, even if we can do that at const eval time. We may // hypothetically be able to allow `dyn StructuralEq` trait objects in the future, @@ -187,16 +193,9 @@ fn get_info_on_unsized_field<'tcx>( ); let unsized_inner_ty = match tail.kind() { ty::Slice(t) => *t, - ty::Str => tail, _ => bug!("expected Slice or Str"), }; - // Have to adjust type for ty::Str - let unsized_inner_ty = match unsized_inner_ty.kind() { - ty::Str => tcx.mk_ty(ty::Uint(ty::UintTy::U8)), - _ => unsized_inner_ty, - }; - // Get the number of elements in the unsized field let num_elems = last_valtree.unwrap_branch().len(); @@ -215,10 +214,6 @@ fn create_pointee_place<'tcx>( // We need to create `Allocation`s for custom DSTs let (unsized_inner_ty, num_elems) = get_info_on_unsized_field(ty, valtree, tcx); - let unsized_inner_ty = match unsized_inner_ty.kind() { - ty::Str => tcx.mk_ty(ty::Uint(ty::UintTy::U8)), - _ => unsized_inner_ty, - }; let unsized_inner_ty_size = tcx.layout_of(ty::ParamEnv::empty().and(unsized_inner_ty)).unwrap().layout.size(); debug!(?unsized_inner_ty, ?unsized_inner_ty_size, ?num_elems); @@ -317,7 +312,6 @@ pub fn valtree_to_const_value<'tcx>( | ty::GeneratorWitnessMIR(..) | ty::FnPtr(_) | ty::RawPtr(_) - | ty::Str | ty::Slice(_) | ty::Dynamic(..) => bug!("no ValTree should have been created for type {:?}", ty.kind()), } @@ -353,7 +347,16 @@ fn valtree_into_mplace<'tcx>( intern_const_alloc_recursive(ecx, InternKind::Constant, &pointee_place).unwrap(); let imm = match inner_ty.kind() { - ty::Slice(_) | ty::Str => { + ty::Slice(_) => { + let len = valtree.unwrap_branch().len(); + let len_scalar = Scalar::from_machine_usize(len as u64, &tcx); + + Immediate::ScalarPair( + Scalar::from_maybe_pointer((*pointee_place).ptr, &tcx), + len_scalar, + ) + } + ty::Adt(def, _) if def.is_str() => { let len = valtree.unwrap_branch().len(); let len_scalar = Scalar::from_machine_usize(len as u64, &tcx); @@ -368,7 +371,7 @@ fn valtree_into_mplace<'tcx>( ecx.write_immediate(imm, &place.into()).unwrap(); } - ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Str | ty::Slice(_) => { + ty::Adt(_, _) | ty::Tuple(_) | ty::Array(_, _) | ty::Slice(_) => { let branches = valtree.unwrap_branch(); // Need to downcast place for enums @@ -396,7 +399,8 @@ fn valtree_into_mplace<'tcx>( debug!(?i, ?inner_valtree); let mut place_inner = match ty.kind() { - ty::Str | ty::Slice(_) => ecx.mplace_index(&place, i as u64).unwrap(), + ty::Adt(def, _) if def.is_str() => ecx.mplace_index(&place, i as u64).unwrap(), + ty::Slice(_) => ecx.mplace_index(&place, i as u64).unwrap(), _ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) && i == branches.len() - 1 => { diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index d13fed7a9c263..b945ac8ce218f 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -573,6 +573,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(Some((layout.size, layout.align.abi))); } match layout.ty.kind() { + // FIXME(str): Do we need this? + ty::Adt(def, _) if def.is_str() => { + let len = metadata.unwrap_meta().to_machine_usize(self)?; + let elem = layout.field(self, 0); + + // Make sure the slice is not too big. + let size = elem.size.bytes().saturating_mul(len); // we rely on `max_size_of_val` being smaller than `u64::MAX`. + let size = Size::from_bytes(size); + if size > self.max_size_of_val() { + throw_ub!(InvalidMeta("slice is bigger than largest supported object")); + } + Ok(Some((size, elem.align.abi))) + } + ty::Adt(..) | ty::Tuple(..) => { // First get the size of all statically known fields. // Don't use type_of::sizing_type_of because that expects t to be sized, @@ -638,7 +652,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(Some(self.get_vtable_size_and_align(vtable)?)) } - ty::Slice(_) | ty::Str => { + ty::Slice(_) => { let len = metadata.unwrap_meta().to_machine_usize(self)?; let elem = layout.field(self, 0); diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs index 907f014dfb518..b98e62f0f3ac4 100644 --- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs +++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs @@ -90,7 +90,6 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>( | ty::Uint(_) | ty::Float(_) | ty::Foreign(_) - | ty::Str | ty::Array(_, _) | ty::Slice(_) | ty::RawPtr(_) diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs index 6f9dcc2fe8e05..e51ec4d82b483 100644 --- a/compiler/rustc_const_eval/src/interpret/place.rs +++ b/compiler/rustc_const_eval/src/interpret/place.rs @@ -229,7 +229,10 @@ impl<'tcx, Prov: Provenance> MPlaceTy<'tcx, Prov> { if self.layout.is_unsized() { // We need to consult `meta` metadata match self.layout.ty.kind() { - ty::Slice(..) | ty::Str => self.mplace.meta.unwrap_meta().to_machine_usize(cx), + ty::Slice(..) => self.mplace.meta.unwrap_meta().to_machine_usize(cx), + ty::Adt(adt, _) if adt.is_str() => { + self.mplace.meta.unwrap_meta().to_machine_usize(cx) + } _ => bug!("len not supported on unsized type {:?}", self.layout.ty), } } else { diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs index 291464ab58ae2..906012fa6771b 100644 --- a/compiler/rustc_const_eval/src/interpret/projection.rs +++ b/compiler/rustc_const_eval/src/interpret/projection.rs @@ -200,8 +200,9 @@ where } _ => span_bug!( self.cur_span(), - "`mplace_index` called on non-array type {:?}", - base.layout.ty + "`mplace_index` called on non-array type {:?} with abi {:?}", + base.layout.ty, + base.layout.fields ), } } diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs index aa539516d5e50..f8b3d769b3cde 100644 --- a/compiler/rustc_const_eval/src/interpret/validity.rs +++ b/compiler/rustc_const_eval/src/interpret/validity.rs @@ -347,7 +347,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' ); // FIXME: check if the type/trait match what ty::Dynamic says? } - ty::Slice(..) | ty::Str => { + ty::Slice(..) => { let _len = meta.unwrap_meta().to_machine_usize(self.ecx)?; // We do not check that `len * elem_size <= isize::MAX`: // that is only required for references, and there it falls out of the @@ -590,7 +590,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, ' | ty::Tuple(..) | ty::Array(..) | ty::Slice(..) - | ty::Str | ty::Dynamic(..) | ty::Closure(..) | ty::Generator(..) => Ok(false), @@ -813,15 +812,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M> fields: impl Iterator>, ) -> InterpResult<'tcx> { match op.layout.ty.kind() { - ty::Str => { - let mplace = op.assert_mem_place(); // strings are unsized and hence never immediate - let len = mplace.len(self.ecx)?; - try_validation!( - self.ecx.read_bytes_ptr_strip_provenance(mplace.ptr, Size::from_bytes(len)), - self.path, - InvalidUninitBytes(..) => { "uninitialized data in `str`" }, - ); - } ty::Array(tys, ..) | ty::Slice(tys) // This optimization applies for types that can hold arbitrary bytes (such as // integer and floating point types) or for structs or tuples with no fields. diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 4e80a28518668..0cc73e9aa87c5 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -39,7 +39,6 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Array(_, _) | ty::Slice(_) | ty::RawPtr(_) diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs index 0454633091568..0fac26d8afd58 100644 --- a/compiler/rustc_hir/src/lang_items.rs +++ b/compiler/rustc_hir/src/lang_items.rs @@ -328,6 +328,7 @@ language_item_table! { RangeTo, sym::RangeTo, range_to_struct, Target::Struct, GenericRequirement::None; String, sym::String, string, Target::Struct, GenericRequirement::None; + Str, sym::str, str_type, Target::Struct, GenericRequirement::Exact(0); } pub enum GenericRequirement { diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs index c1b0237b2d1f1..5f13a2433fdf1 100644 --- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs +++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs @@ -213,7 +213,6 @@ impl<'tcx> InherentCollect<'tcx> { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Array(..) | ty::Slice(_) | ty::RawPtr(_) diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs index 7d381d8902ac2..477155e4b3c99 100644 --- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs +++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs @@ -219,7 +219,6 @@ fn do_orphan_check_impl<'tcx>( | ty::Int(..) | ty::Uint(..) | ty::Float(..) - | ty::Str | ty::Array(..) | ty::Slice(..) | ty::RawPtr(..) diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs index b0cf0387f87a9..b7d1b2be11c45 100644 --- a/compiler/rustc_hir_analysis/src/variance/constraints.rs +++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs @@ -214,7 +214,6 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Never | ty::Foreign(..) => { // leaf type -- noop diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 8e21c084841d0..f30fe8cfd26a0 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -101,7 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Ok(match *t.kind() { - ty::Slice(_) | ty::Str => Some(PointerKind::Length), + ty::Slice(_) => Some(PointerKind::Length), ty::Dynamic(ref tty, _, ty::Dyn) => Some(PointerKind::VTable(tty.principal_def_id())), ty::Adt(def, substs) if def.is_struct() => match def.non_enum_variant().fields.last() { None => Some(PointerKind::Thin), @@ -1101,7 +1101,7 @@ impl<'a, 'tcx> CastCheck<'tcx> { let derefed = fcx .autoderef(self.expr_span, self.expr_ty) .silence_errors() - .find(|t| matches!(t.0.kind(), ty::Str | ty::Slice(..))); + .find(|t| matches!(t.0.kind(), ty::Slice(..)) || t.0.is_str()); if let Some((deref_ty, _)) = derefed { // Give a note about what the expr derefs to. diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs index c4905a934cb4e..40ac22e76d8d2 100644 --- a/compiler/rustc_hir_typeck/src/demand.rs +++ b/compiler/rustc_hir_typeck/src/demand.rs @@ -1224,7 +1224,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match (&expr.kind, expected.kind(), checked_ty.kind()) { (_, &ty::Ref(_, exp, _), &ty::Ref(_, check, _)) => match (exp.kind(), check.kind()) { - (&ty::Str, &ty::Array(arr, _) | &ty::Slice(arr)) if arr == self.tcx.types.u8 => { + (&ty::Adt(def, _), &ty::Array(arr, _) | &ty::Slice(arr)) if def.is_str() && arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind && let Ok(src) = sm.span_to_snippet(sp) && replace_prefix(&src, "b\"", "\"").is_some() @@ -1240,7 +1240,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { )); } } - (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Str) if arr == self.tcx.types.u8 => { + (&ty::Array(arr, _) | &ty::Slice(arr), &ty::Adt(def, _)) if def.is_str() && arr == self.tcx.types.u8 => { if let hir::ExprKind::Lit(_) = expr.kind && let Ok(src) = sm.span_to_snippet(sp) && replace_prefix(&src, "\"", "b\"").is_some() diff --git a/compiler/rustc_hir_typeck/src/expectation.rs b/compiler/rustc_hir_typeck/src/expectation.rs index 4f086cf597d88..dbdfde63dc190 100644 --- a/compiler/rustc_hir_typeck/src/expectation.rs +++ b/compiler/rustc_hir_typeck/src/expectation.rs @@ -74,7 +74,8 @@ impl<'a, 'tcx> Expectation<'tcx> { /// for examples of where this comes up,. pub(super) fn rvalue_hint(fcx: &FnCtxt<'a, 'tcx>, ty: Ty<'tcx>) -> Expectation<'tcx> { match fcx.tcx.struct_tail_without_normalization(ty).kind() { - ty::Slice(_) | ty::Str | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty), + ty::Slice(_) | ty::Dynamic(..) => ExpectRvalueLikeUnsized(ty), + ty::Adt(def, _) if def.is_str() => ExpectRvalueLikeUnsized(ty), _ => ExpectHasType(ty), } } diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index bb235a4836153..c675320df9af4 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -2402,7 +2402,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ty::RawPtr(..) => { self.suggest_first_deref_field(&mut err, expr, base, ident); } - ty::Adt(def, _) if !def.is_enum() => { + ty::Adt(def, _) if !def.is_enum() && !def.is_str() => { self.suggest_fields_on_recordish(&mut err, def, ident, expr.span); } ty::Param(param_ty) => { diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs index 16b0d48002efc..505eca2bc0058 100644 --- a/compiler/rustc_hir_typeck/src/method/probe.rs +++ b/compiler/rustc_hir_typeck/src/method/probe.rs @@ -689,7 +689,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Array(..) | ty::Slice(_) | ty::RawPtr(_) diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs index 54890489f8b8f..c42d03707cb98 100644 --- a/compiler/rustc_hir_typeck/src/method/suggest.rs +++ b/compiler/rustc_hir_typeck/src/method/suggest.rs @@ -2131,7 +2131,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { | ty::Uint(_) | ty::Float(_) | ty::Adt(_, _) - | ty::Str | ty::Alias(ty::Projection, _) | ty::Param(_) => format!("{deref_ty}"), // we need to test something like <&[_]>::len or <(&[u32])>::len diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs index ba72aefe39c16..753954a83e3dd 100644 --- a/compiler/rustc_hir_typeck/src/op.rs +++ b/compiler/rustc_hir_typeck/src/op.rs @@ -551,11 +551,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { match (lhs_ty.kind(), rhs_ty.kind()) { (&Ref(_, l_ty, _), &Ref(_, r_ty, _)) // &str or &String + &str, &String or &&str - if (*l_ty.kind() == Str || is_std_string(l_ty)) - && (*r_ty.kind() == Str + if (l_ty.is_str() || is_std_string(l_ty)) + && (r_ty.is_str() || is_std_string(r_ty) || matches!( - r_ty.kind(), Ref(_, inner_ty, _) if *inner_ty.kind() == Str + r_ty.kind(), Ref(_, inner_ty, _) if inner_ty.is_str() )) => { if let IsAssign::No = is_assign { // Do not supply this message if `&str += &str` @@ -580,7 +580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { true } (&Ref(_, l_ty, _), &Adt(..)) // Handle `&str` & `&String` + `String` - if (*l_ty.kind() == Str || is_std_string(l_ty)) && is_std_string(rhs_ty) => + if (l_ty.is_str() || is_std_string(l_ty)) && is_std_string(rhs_ty) => { err.span_label( op.span, @@ -694,8 +694,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } } - Str | Never | Char | Tuple(_) | Array(_, _) => {} - Ref(_, lty, _) if *lty.kind() == Str => {} + Never | Char | Tuple(_) | Array(_, _) => {} + ty::Adt(def, _) if def.is_str() => {} + Ref(_, lty, _) if lty.is_str() => {} _ => { self.note_unmet_impls_on_type(&mut err, errors); } diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs index 52236ae56eeaa..9b4801c0a3e97 100644 --- a/compiler/rustc_hir_typeck/src/pat.rs +++ b/compiler/rustc_hir_typeck/src/pat.rs @@ -414,7 +414,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let expected = self.resolve_vars_if_possible(expected); pat_ty = match expected.kind() { ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => expected, - ty::Str => tcx.mk_static_str(), + ty::Adt(def, _) if def.is_str() => tcx.mk_static_str(), _ => pat_ty, }; } diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs index f1b32cd941ed1..b44a89825e3cc 100644 --- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs +++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs @@ -441,7 +441,6 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for Canonicalizer<'cx, 'tcx> { | ty::Uint(..) | ty::Float(..) | ty::Adt(..) - | ty::Str | ty::Error(_) | ty::Array(..) | ty::Slice(..) diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs index e3d9566917125..be97e739b9e9b 100644 --- a/compiler/rustc_infer/src/infer/outlives/components.rs +++ b/compiler/rustc_infer/src/infer/outlives/components.rs @@ -169,7 +169,6 @@ fn compute_components<'tcx>( ty::Never | // ... ty::Adt(..) | // OutlivesNominalType ty::Foreign(..) | // OutlivesNominalType - ty::Str | // OutlivesScalar (ish) ty::Slice(..) | // ... ty::RawPtr(..) | // ... ty::Ref(..) | // OutlivesReference diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs index 7a50b6aec87a6..39b2bcc70aa7d 100644 --- a/compiler/rustc_lint/src/builtin.rs +++ b/compiler/rustc_lint/src/builtin.rs @@ -2920,7 +2920,7 @@ impl ClashingExternDeclarations { | (Alias(ty::Opaque, ..), Alias(ty::Opaque, ..)) => false, // These definitely should have been caught above. - (Bool, Bool) | (Char, Char) | (Never, Never) | (Str, Str) => unreachable!(), + (Bool, Bool) | (Char, Char) | (Never, Never) => unreachable!(), // An Adt and a primitive or pointer type. This can be FFI-safe if non-null // enum layout optimisation is being applied. diff --git a/compiler/rustc_lint/src/non_fmt_panic.rs b/compiler/rustc_lint/src/non_fmt_panic.rs index 4a02c6cce47ed..548f30ec97264 100644 --- a/compiler/rustc_lint/src/non_fmt_panic.rs +++ b/compiler/rustc_lint/src/non_fmt_panic.rs @@ -146,7 +146,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc // If this is a &str or String, we can confidently give the `"{}", ` suggestion. let is_str = matches!( ty.kind(), - ty::Ref(_, r, _) if *r.kind() == ty::Str, + ty::Ref(_, r, _) if r.is_str(), ) || matches!( ty.ty_adt_def(), Some(ty_def) if Some(ty_def.did()) == cx.tcx.lang_items().string(), diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index b0a5d3674ad27..20c4ad40c4159 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -894,6 +894,13 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { if def.is_phantom_data() { return FfiPhantom(ty); } + if def.is_str() { + return FfiUnsafe { + ty, + reason: fluent::lint_improper_ctypes_str_reason, + help: Some(fluent::lint_improper_ctypes_str_help), + }; + } match def.adt_kind() { AdtKind::Struct | AdtKind::Union => { if !def.repr().c() && !def.repr().transparent() { @@ -1017,12 +1024,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> { FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_dyn, help: None } } - ty::Str => FfiUnsafe { - ty, - reason: fluent::lint_improper_ctypes_str_reason, - help: Some(fluent::lint_improper_ctypes_str_help), - }, - ty::Tuple(..) => FfiUnsafe { ty, reason: fluent::lint_improper_ctypes_tuple_reason, diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 10ac7e0d39af6..d4148a5f7a0a2 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -2861,7 +2861,7 @@ fn pretty_print_const_value<'tcx>( return Ok(()); } } - ty::Str => { + ty::Adt(def, _) if def.is_str() => { // The `inspect` here is okay since we checked the bounds, and `str` carries // no provenance (we have an active `str` reference here). We don't use this // result to affect interpreter execution. diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 099a784511827..210a93887ae45 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -48,7 +48,9 @@ bitflags! { /// (i.e., this flag is never set unless this ADT is an enum). const IS_VARIANT_LIST_NON_EXHAUSTIVE = 1 << 8; /// Indicates whether the type is `UnsafeCell`. - const IS_UNSAFE_CELL = 1 << 9; + const IS_UNSAFE_CELL = 1 << 9; + /// Indicates whether the type is `str`. + const IS_STR = 1 << 10; } } @@ -247,6 +249,9 @@ impl AdtDefData { if Some(did) == tcx.lang_items().unsafe_cell_type() { flags |= AdtFlags::IS_UNSAFE_CELL; } + if Some(did) == tcx.lang_items().str_type() { + flags |= AdtFlags::IS_STR; + } AdtDefData { did, variants, flags, repr } } @@ -345,6 +350,11 @@ impl<'tcx> AdtDef<'tcx> { self.flags().contains(AdtFlags::IS_MANUALLY_DROP) } + #[inline] + pub fn is_str(self) -> bool { + self.flags().contains(AdtFlags::IS_STR) + } + /// Returns `true` if this type has a destructor. pub fn has_dtor(self, tcx: TyCtxt<'tcx>) -> bool { self.destructor(tcx).is_some() diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index a803fca0d5b89..9db534794cc8b 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -88,7 +88,7 @@ impl<'tcx> ValTree<'tcx> { match ty.kind() { ty::Ref(_, inner_ty, _) => match inner_ty.kind() { // `&str` can be interpreted as raw bytes - ty::Str => {} + ty::Adt(def, _) if def.is_str() => {} // `&[u8]` can be interpreted as raw bytes ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {} // other `&_` can't be interpreted as raw bytes diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index b7566cc46389c..19494e0f6a254 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -259,7 +259,6 @@ pub struct CommonTypes<'tcx> { pub u128: Ty<'tcx>, pub f32: Ty<'tcx>, pub f64: Ty<'tcx>, - pub str_: Ty<'tcx>, pub never: Ty<'tcx>, pub self_param: Ty<'tcx>, @@ -308,7 +307,6 @@ impl<'tcx> CommonTypes<'tcx> { u128: mk(Uint(ty::UintTy::U128)), f32: mk(Float(ty::FloatTy::F32)), f64: mk(Float(ty::FloatTy::F64)), - str_: mk(Str), self_param: mk(ty::Param(ty::ParamTy { index: 0, name: kw::SelfUpper })), trait_object_dummy_self: mk(Infer(ty::FreshTy(0))), @@ -1292,7 +1290,7 @@ macro_rules! sty_debug_print { for &InternedInSet(t) in types { let variant = match t.internee { ty::Bool | ty::Char | ty::Int(..) | ty::Uint(..) | - ty::Float(..) | ty::Str | ty::Never => continue, + ty::Float(..) | ty::Never => continue, ty::Error(_) => /* unimportant */ continue, $(ty::$variant(..) => &mut $variant,)* }; @@ -1899,7 +1897,7 @@ impl<'tcx> TyCtxt<'tcx> { #[inline] pub fn mk_str(self) -> Ty<'tcx> { - self.mk_ty(Str) + self.mk_adt(self.adt_def(self.require_lang_item(LangItem::Str, None)), List::empty()) } pub fn mk_param_from_def(self, param: &ty::GenericParamDef) -> GenericArg<'tcx> { diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index 0a30ae9d0aa78..aab84b14d144f 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -29,7 +29,6 @@ impl<'tcx> Ty<'tcx> { matches!( self.kind(), Bool | Char - | Str | Int(_) | Uint(_) | Float(_) @@ -39,7 +38,9 @@ impl<'tcx> Ty<'tcx> { | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_) ) - ) + ) || matches!(self.kind(), + Adt(def, _) if def.is_str(), + ) // FIXME(str): Should we treat str as primitive? } /// Whether the type is succinctly representable as a type instead of just referred to with a @@ -48,7 +49,6 @@ impl<'tcx> Ty<'tcx> { match self.kind() { Bool | Char - | Str | Int(_) | Uint(_) | Float(_) @@ -60,6 +60,7 @@ impl<'tcx> Ty<'tcx> { ) => true, Ref(_, x, _) | Array(x, _) | Slice(x) => x.peel_refs().is_simple_ty(), Tuple(tys) if tys.is_empty() => true, + Adt(def, _) if def.is_str() => true, _ => false, } } diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs index bd78705cdb59b..b4551ad41d240 100644 --- a/compiler/rustc_middle/src/ty/error.rs +++ b/compiler/rustc_middle/src/ty/error.rs @@ -290,8 +290,8 @@ impl<'tcx> Ty<'tcx> { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Never => "type".into(), + ty::Adt(def, _) if def.is_str() => "type".into(), ty::Tuple(ref tys) if tys.is_empty() => "unit type".into(), ty::Adt(def, _) => def.descr().into(), ty::Foreign(_) => "extern type".into(), diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs index 9afa37e9ef3ee..e209612875ca6 100644 --- a/compiler/rustc_middle/src/ty/fast_reject.rs +++ b/compiler/rustc_middle/src/ty/fast_reject.rs @@ -94,8 +94,9 @@ pub fn simplify_type<'tcx>( ty::Int(int_type) => Some(IntSimplifiedType(int_type)), ty::Uint(uint_type) => Some(UintSimplifiedType(uint_type)), ty::Float(float_type) => Some(FloatSimplifiedType(float_type)), + // FIXME(str): Do we need this? We could just treat it like an ADT. + ty::Adt(def, _) if def.is_str() => Some(StrSimplifiedType), ty::Adt(def, _) => Some(AdtSimplifiedType(def.did())), - ty::Str => Some(StrSimplifiedType), ty::Array(..) => Some(ArraySimplifiedType), ty::Slice(..) => Some(SliceSimplifiedType), ty::RawPtr(ptr) => Some(PtrSimplifiedType(ptr.mutbl)), @@ -197,7 +198,6 @@ impl DeepRejectCtxt { | ty::Uint(_) | ty::Float(_) | ty::Adt(..) - | ty::Str | ty::Array(..) | ty::Slice(..) | ty::RawPtr(..) @@ -225,7 +225,6 @@ impl DeepRejectCtxt { | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Never | ty::Foreign(_) => obligation_ty == impl_ty, ty::Ref(_, obl_ty, obl_mutbl) => match k { diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs index 258bc9c3e4188..841f8250edf86 100644 --- a/compiler/rustc_middle/src/ty/flags.rs +++ b/compiler/rustc_middle/src/ty/flags.rs @@ -95,7 +95,6 @@ impl FlagComputation { | &ty::Float(_) | &ty::Uint(_) | &ty::Never - | &ty::Str | &ty::Foreign(..) => {} &ty::Error(_) => self.add_flags(TypeFlags::HAS_ERROR), diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 4c2855821384b..1553df29617d9 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -713,7 +713,7 @@ where } } else { match tcx.struct_tail_erasing_lifetimes(pointee, cx.param_env()).kind() { - ty::Slice(_) | ty::Str => tcx.types.usize, + ty::Slice(_) => tcx.types.usize, ty::Dynamic(_, _, ty::Dyn) => mk_dyn_vtable(), _ => bug!("TyAndLayout::field({:?}): not applicable", this), } @@ -724,7 +724,6 @@ where // Arrays and slices. ty::Array(element, _) | ty::Slice(element) => TyMaybeWithLayout::Ty(element), - ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8), // Tuples, generators and closures. ty::Closure(_, ref substs) => field_ty_or_layout( diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index 90bf3288ccf54..7b7daab05d7e2 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -272,7 +272,6 @@ fn characteristic_def_id_of_type_cached<'a>( | ty::Char | ty::Int(_) | ty::Uint(_) - | ty::Str | ty::FnPtr(_) | ty::Alias(..) | ty::Placeholder(..) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 7ba531fba7867..54b37b088aca0 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -597,7 +597,6 @@ pub trait PrettyPrinter<'tcx>: | ty::Foreign(_) | ty::Bool | ty::Char - | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { @@ -707,6 +706,8 @@ pub trait PrettyPrinter<'tcx>: } ty::BoundTyKind::Param(_, s) => p!(write("{}", s)), }, + // We need to special case this, because otherwise we'll call it `core::str::str`. + ty::Adt(def, _) if def.is_str() => p!("str"), ty::Adt(def, substs) => { p!(print_def_path(def.did(), substs)); } @@ -778,7 +779,6 @@ pub trait PrettyPrinter<'tcx>: } } } - ty::Str => p!("str"), ty::Generator(did, substs, movability) => { p!(write("[")); let generator_kind = self.tcx().generator_kind(did).unwrap(); @@ -1560,7 +1560,7 @@ pub trait PrettyPrinter<'tcx>: }); return self.pretty_print_byte_str(bytes); } - ty::Str => { + ty::Adt(def, _) if def.is_str() => { let bytes = valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| { bug!("expected to convert valtree to raw bytes for type {:?}", ty) }); diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs index 890dabde1f73d..d947da32b46cd 100644 --- a/compiler/rustc_middle/src/ty/relate.rs +++ b/compiler/rustc_middle/src/ty/relate.rs @@ -422,7 +422,6 @@ pub fn super_relate_tys<'tcx, R: TypeRelation<'tcx>>( | (&ty::Int(_), _) | (&ty::Uint(_), _) | (&ty::Float(_), _) - | (&ty::Str, _) if a == b => { Ok(a) diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs index 1ef66b01ea0c6..1bedbfd94a41a 100644 --- a/compiler/rustc_middle/src/ty/structural_impls.rs +++ b/compiler/rustc_middle/src/ty/structural_impls.rs @@ -666,7 +666,6 @@ impl<'tcx> TypeSuperFoldable<'tcx> for Ty<'tcx> { ty::Bool | ty::Char - | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) @@ -712,7 +711,6 @@ impl<'tcx> TypeSuperVisitable<'tcx> for Ty<'tcx> { ty::Bool | ty::Char - | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index b3b2a4fd0e5da..3030b669993a9 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1816,7 +1816,7 @@ impl<'tcx> Ty<'tcx> { /// Returns `true` if this type is a `str`. #[inline] pub fn is_str(self) -> bool { - *self.kind() == Str + self.ty_adt_def().map_or(false, |def| def.is_str()) } #[inline] @@ -1854,10 +1854,10 @@ impl<'tcx> Ty<'tcx> { } } - pub fn sequence_element_type(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> { + // FIXME(str): Remove tcx from this + pub fn sequence_element_type(self) -> Ty<'tcx> { match self.kind() { Array(ty, _) | Slice(ty) => *ty, - Str => tcx.types.u8, _ => bug!("`sequence_element_type` called on non-sequence value: {}", self), } } @@ -2203,7 +2203,6 @@ impl<'tcx> Ty<'tcx> { | ty::Float(_) | ty::Adt(..) | ty::Foreign(_) - | ty::Str | ty::Array(..) | ty::Slice(_) | ty::RawPtr(_) @@ -2263,7 +2262,7 @@ impl<'tcx> Ty<'tcx> { // a.k.a. unit type, which is Sized | ty::Tuple(..) => (tcx.types.unit, false), - ty::Str | ty::Slice(_) => (tcx.types.usize, false), + ty::Slice(_) => (tcx.types.usize, false), ty::Dynamic(..) => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); (tcx.bound_type_of(dyn_metadata).subst(tcx, &[tail.into()]), false) @@ -2342,7 +2341,7 @@ impl<'tcx> Ty<'tcx> { | ty::Never | ty::Error(_) => true, - ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false, + ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => false, ty::Tuple(tys) => tys.iter().all(|ty| ty.is_trivially_sized(tcx)), @@ -2372,8 +2371,8 @@ impl<'tcx> Ty<'tcx> { match self.kind() { ty::Bool | ty::Char | ty::Never => true, - // These aren't even `Clone` - ty::Str | ty::Slice(..) | ty::Foreign(..) | ty::Dynamic(..) => false, + // unsized types cannot be `Clone` or `Copy` + ty::Slice(..) | ty::Foreign(..) | ty::Dynamic(..) => false, ty::Infer(ty::InferTy::FloatVar(_) | ty::InferTy::IntVar(_)) | ty::Int(..) diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 796164b0d6af3..f8b7a79dc8a42 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -949,13 +949,14 @@ impl<'tcx> Ty<'tcx> { | ty::Float(_) | ty::Bool | ty::Char - | ty::Str | ty::Never | ty::Ref(..) | ty::RawPtr(_) | ty::FnDef(..) | ty::Error(_) | ty::FnPtr(_) => true, + // FIXME(str): make sure this is true :^) + ty::Adt(def, _) if def.is_str() => true, ty::Tuple(fields) => fields.iter().all(Self::is_trivially_freeze), ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_freeze(), ty::Adt(..) @@ -989,13 +990,14 @@ impl<'tcx> Ty<'tcx> { | ty::Float(_) | ty::Bool | ty::Char - | ty::Str | ty::Never | ty::Ref(..) | ty::RawPtr(_) | ty::FnDef(..) | ty::Error(_) | ty::FnPtr(_) => true, + // FIXME(str): make sure this is true :^) + ty::Adt(def, _) if def.is_str() => true, ty::Tuple(fields) => fields.iter().all(Self::is_trivially_unpin), ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_unpin(), ty::Adt(..) @@ -1106,7 +1108,7 @@ impl<'tcx> Ty<'tcx> { ty::Adt(..) => tcx.has_structural_eq_impls(self), // Primitive types that satisfy `Eq`. - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Str | ty::Never => true, + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Never => true, // Composite types that satisfy `Eq` when all of their fields do. // @@ -1234,8 +1236,9 @@ pub fn needs_drop_components<'tcx>( | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::RawPtr(_) - | ty::Ref(..) - | ty::Str => Ok(SmallVec::new()), + | ty::Ref(..) => Ok(SmallVec::new()), + + ty::Adt(def, _) if def.is_str() => Ok(SmallVec::new()), // Foreign types can never have destructors. ty::Foreign(..) => Ok(SmallVec::new()), @@ -1285,7 +1288,6 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool { | ty::Float(_) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) - | ty::Str | ty::RawPtr(_) | ty::Ref(..) | ty::FnDef(..) diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs index 182945b9c3db1..d91e7d4533e91 100644 --- a/compiler/rustc_middle/src/ty/walk.rs +++ b/compiler/rustc_middle/src/ty/walk.rs @@ -142,7 +142,6 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>) | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Infer(_) | ty::Param(_) | ty::Never diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs index cd0e69328634b..bdefd2c027b9d 100644 --- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs +++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs @@ -304,7 +304,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { // to the same MIR as `let x = ();`. // first process the set of fields - let el_ty = expr.ty.sequence_element_type(this.tcx); + let el_ty = expr.ty.sequence_element_type(); let fields: Vec<_> = fields .into_iter() .copied() diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs index ff88d00135173..5f3474abefa1f 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs @@ -345,7 +345,7 @@ impl<'tcx> ConstToPat<'tcx> { } // `&str` is represented as `ConstValue::Slice`, let's keep using this // optimization for now. - ty::Str => PatKind::Constant { value: cv }, + ty::Adt(def, _) if def.is_str() => PatKind::Constant { value: cv }, // `b"foo"` produces a `&[u8; 3]`, but you can't use constants of array type when // matching against references, you can only use byte string literals. // The typechecker has a special case for byte string literals, by treating them diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs index aba5429da435f..6a25174435cc2 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs @@ -1019,8 +1019,10 @@ impl<'tcx> SplitWildcard<'tcx> { } ty::Never => smallvec![], _ if cx.is_uninhabited(pcx.ty) => smallvec![], + // `str` is not exhaustive + ty::Adt(def, _) if def.is_str() => smallvec![NonExhaustive], ty::Adt(..) | ty::Tuple(..) | ty::Ref(..) => smallvec![Single], - // This type is one for which we cannot list constructors, like `str` or `f64`. + // This type is one for which we cannot list constructors, like `f64`. _ => smallvec![NonExhaustive], }; diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs index 7d2146214c6dc..2316b042dc2f5 100644 --- a/compiler/rustc_mir_transform/src/add_retag.rs +++ b/compiler/rustc_mir_transform/src/add_retag.rs @@ -22,7 +22,6 @@ fn may_contain_reference<'tcx>(ty: Ty<'tcx>, depth: u32, tcx: TyCtxt<'tcx>) -> b | ty::Uint(_) | ty::RawPtr(..) | ty::FnPtr(..) - | ty::Str | ty::FnDef(..) | ty::Never => false, // References diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs index 31a3ffbb1d891..f931c7af78dcf 100644 --- a/compiler/rustc_monomorphize/src/collector.rs +++ b/compiler/rustc_monomorphize/src/collector.rs @@ -1072,7 +1072,7 @@ fn find_vtable_types_for_unsizing<'tcx>( let tail = tcx.struct_tail_erasing_lifetimes(ty, param_env); match tail.kind() { ty::Foreign(..) => false, - ty::Str | ty::Slice(..) | ty::Dynamic(..) => true, + ty::Slice(..) | ty::Dynamic(..) => true, _ => bug!("unexpected unsized tail: {:?}", tail), } }; diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4355286153223..653e1bf55d195 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -261,7 +261,6 @@ where | ty::Int(..) | ty::Uint(..) | ty::Float(..) - | ty::Str | ty::Never | ty::Array(..) | ty::Slice(..) diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index 710f38264036c..ad6085227dd3f 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -481,7 +481,7 @@ fn encode_ty<'tcx>( typeid.push_str(&s); } - ty::Str => { + ty::Adt(def, _) if def.is_str() => { // u3str as vendor extended type let mut s = String::from("u3str"); compress(dict, DictKey::Ty(ty, TyQ::None), &mut s); @@ -666,7 +666,6 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio | ty::Uint(..) | ty::Float(..) | ty::Char - | ty::Str | ty::Never | ty::Foreign(..) | ty::Dynamic(..) => {} diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs index 00d1ff5ceedf7..0e20890b4ca02 100644 --- a/compiler/rustc_symbol_mangling/src/v0.rs +++ b/compiler/rustc_symbol_mangling/src/v0.rs @@ -355,7 +355,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { let basic_type = match ty.kind() { ty::Bool => "b", ty::Char => "c", - ty::Str => "e", + ty::Adt(def, _) if def.is_str() => "e", ty::Tuple(_) if ty.is_unit() => "u", ty::Int(IntTy::I8) => "a", ty::Int(IntTy::I16) => "s", @@ -390,7 +390,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { match *ty.kind() { // Basic types, handled above. - ty::Bool | ty::Char | ty::Str | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Never => { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Never => { unreachable!() } ty::Tuple(_) if ty.is_unit() => unreachable!(), @@ -622,43 +622,41 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> { hir::Mutability::Mut => "Q", }); - match inner_ty.kind() { - ty::Str if mutbl.is_not() => { - match ct.kind() { - ty::ConstKind::Value(valtree) => { - let slice = - valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| { - bug!( + if inner_ty.is_str() && mutbl.is_not() { + match ct.kind() { + ty::ConstKind::Value(valtree) => { + let slice = + valtree.try_to_raw_bytes(self.tcx(), ty).unwrap_or_else(|| { + bug!( "expected to get raw bytes from valtree {:?} for type {:}", - valtree, ty + valtree, + ty ) - }); - let s = std::str::from_utf8(slice).expect("non utf8 str from miri"); + }); + let s = std::str::from_utf8(slice).expect("non utf8 str from miri"); - self.push("e"); + self.push("e"); - // FIXME(eddyb) use a specialized hex-encoding loop. - for byte in s.bytes() { - let _ = write!(self.out, "{byte:02x}"); - } - - self.push("_"); + // FIXME(eddyb) use a specialized hex-encoding loop. + for byte in s.bytes() { + let _ = write!(self.out, "{byte:02x}"); } - _ => { - bug!("symbol_names: unsupported `&str` constant: {:?}", ct); - } + self.push("_"); + } + + _ => { + bug!("symbol_names: unsupported `&str` constant: {:?}", ct); } } - _ => { - let pointee_ty = ct - .ty() - .builtin_deref(true) - .expect("tried to dereference on non-ptr type") - .ty; - let dereferenced_const = self.tcx.mk_const(ct.kind(), pointee_ty); - self = dereferenced_const.print(self)?; - } + } else { + let pointee_ty = ct + .ty() + .builtin_deref(true) + .expect("tried to dereference on non-ptr type") + .ty; + let dereferenced_const = self.tcx.mk_const(ct.kind(), pointee_ty); + self = dereferenced_const.print(self)?; } } diff --git a/compiler/rustc_trait_selection/src/solve/assembly.rs b/compiler/rustc_trait_selection/src/solve/assembly.rs index 126ec60b3d68a..b9f0a3701b6da 100644 --- a/compiler/rustc_trait_selection/src/solve/assembly.rs +++ b/compiler/rustc_trait_selection/src/solve/assembly.rs @@ -377,7 +377,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { | ty::Float(_) | ty::Adt(_, _) | ty::Foreign(_) - | ty::Str | ty::Array(_, _) | ty::Slice(_) | ty::RawPtr(_) @@ -425,7 +424,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> { | ty::Float(_) | ty::Adt(_, _) | ty::Foreign(_) - | ty::Str | ty::Array(_, _) | ty::Slice(_) | ty::RawPtr(_) diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs index 4fea49893a6c6..6f882f3c4f54f 100644 --- a/compiler/rustc_trait_selection/src/solve/project_goals.rs +++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs @@ -384,7 +384,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> { ty::Error(e) => tcx.ty_error_with_guaranteed(*e), - ty::Str | ty::Slice(_) => tcx.types.usize, + ty::Slice(_) => tcx.types.usize, ty::Dynamic(_, _, _) => { let dyn_metadata = tcx.require_lang_item(LangItem::DynMetadata, None); 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 1ee35a86e6264..36dc1d72b02a3 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 @@ -18,7 +18,6 @@ pub(super) fn instantiate_constituent_tys_for_auto_trait<'tcx>( | ty::Float(_) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Str | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never @@ -97,8 +96,7 @@ pub(super) fn instantiate_constituent_tys_for_sized_trait<'tcx>( | ty::Dynamic(_, _, ty::DynStar) | ty::Error(_) => Ok(vec![]), - ty::Str - | ty::Slice(_) + ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) | ty::Alias(..) @@ -145,7 +143,6 @@ pub(super) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>( | ty::Array(..) => Err(NoSolution), ty::Dynamic(..) - | ty::Str | ty::Slice(_) | ty::Generator(_, _, Movability::Static) | ty::Foreign(..) @@ -212,7 +209,6 @@ pub(crate) fn extract_tupled_inputs_and_output_from_callable<'tcx>( | ty::Float(_) | ty::Adt(_, _) | ty::Foreign(_) - | ty::Str | ty::Array(_, _) | ty::Slice(_) | ty::RawPtr(_) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 61f508a7a0750..6f84262b8808c 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -640,7 +640,6 @@ impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> { | ty::Int(..) | ty::Uint(..) | ty::Float(..) - | ty::Str | ty::FnDef(..) | ty::FnPtr(_) | ty::Array(..) diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 4867855c2ae95..854fcd9373ab7 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -1911,8 +1911,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { match t.kind() { ty::Bool => Some(0), ty::Char => Some(1), - ty::Str => Some(2), - ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().string() => Some(2), + ty::Adt(def, _) if def.is_str() || Some(def.did()) == tcx.lang_items().string() => { + Some(2) + } ty::Int(..) | ty::Uint(..) | ty::Float(..) @@ -1958,6 +1959,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> { Some(CandidateSimilarity::Exact { ignoring_lifetimes }) } else if cat_a == cat_b { match (a.kind(), b.kind()) { + // `str` are always equal to the other type in their category, `String` + (ty::Adt(def, _), _) | (_, ty::Adt(def, _)) if def.is_str() => true, (ty::Adt(def_a, _), ty::Adt(def_b, _)) => def_a == def_b, (ty::Foreign(def_a), ty::Foreign(def_b)) => def_a == def_b, // Matching on references results in a lot of unhelpful diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index aa81bc640aa6c..b1742d2bfa23e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -1594,7 +1594,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Float(_) | ty::Adt(..) | ty::Foreign(_) - | ty::Str | ty::Array(..) | ty::Slice(_) | ty::RawPtr(..) @@ -1644,7 +1643,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>( | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Array(..) | ty::Slice(_) | ty::RawPtr(..) diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs index 455b53bfb7d8f..4e70a805816e1 100644 --- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs +++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs @@ -34,10 +34,12 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool { | ty::GeneratorWitnessMIR(..) | ty::RawPtr(_) | ty::Ref(..) - | ty::Str | ty::Foreign(..) | ty::Error(_) => true, + // FIXME(str): Do we need this? + ty::Adt(def, _) if def.is_str() => true, + // [T; N] and [T] have same properties as T. ty::Array(ty, _) | ty::Slice(ty) => trivial_dropck_outlives(tcx, *ty), diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs index 18d7c9b193601..bcbd78320a335 100644 --- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs +++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs @@ -18,9 +18,10 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> { // Don't go into the query for things that can't possibly have lifetimes. match key.value.ty.kind() { ty::Tuple(elems) if elems.is_empty() => Some(vec![]), - ty::Never | ty::Str | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { + ty::Never | ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => { Some(vec![]) } + ty::Adt(def, _) if def.is_str() => Some(vec![]), _ => None, } } diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs index e9f7c3bc4cca2..3a83ad284df5b 100644 --- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs +++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs @@ -753,7 +753,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Float(_) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) - | ty::Str | ty::RawPtr(_) | ty::Ref(..) | ty::FnDef(..) @@ -816,7 +815,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Float(_) | ty::Adt(_, _) | ty::Foreign(_) - | ty::Str | ty::Array(_, _) | ty::Slice(_) | ty::RawPtr(_) diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs index fcc4820c2a6b6..65db217fa5719 100644 --- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs +++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs @@ -1223,7 +1223,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Float(_) | ty::Infer(ty::IntVar(_)) | ty::Infer(ty::FloatVar(_)) - | ty::Str | ty::RawPtr(_) | ty::Ref(..) | ty::FnDef(..) diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 45c4811321a01..8c7d0df5675d0 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2079,7 +2079,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { Where(ty::Binder::dummy(Vec::new())) } - ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, + ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, + + // FIXME(str): We special case this impl for diagnostics reasons. + ty::Adt(def, _) if def.is_str() => None, ty::Tuple(tys) => Where( obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])), @@ -2138,12 +2141,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Dynamic(..) - | ty::Str | ty::Slice(..) | ty::Generator(_, _, hir::Movability::Static) | ty::Foreign(..) | ty::Ref(_, _, hir::Mutability::Mut) => None, + // FIXME(str): We special case this impl for diagnostics reasons. + ty::Adt(def, _) if def.is_str() => None, + ty::Tuple(tys) => { // (*) binder moved here Where(obligation.predicate.rebind(tys.iter().collect())) @@ -2250,7 +2255,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { | ty::Float(_) | ty::FnDef(..) | ty::FnPtr(_) - | ty::Str | ty::Error(_) | ty::Infer(ty::IntVar(_) | ty::FloatVar(_)) | ty::Never diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs index 69b965f3a389a..0c6d719429cb2 100644 --- a/compiler/rustc_trait_selection/src/traits/structural_match.rs +++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs @@ -116,7 +116,7 @@ impl<'tcx> TypeVisitor<'tcx> for Search<'tcx> { // for empty array. return ControlFlow::Continue(()); } - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Str | ty::Never => { + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Never => { // These primitive types are always structural match. // // `Never` is kind of special here, but as it is not inhabitable, this should be fine. diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs index 1136b70a0b91e..4cf5ae0ae3b9b 100644 --- a/compiler/rustc_trait_selection/src/traits/wf.rs +++ b/compiler/rustc_trait_selection/src/traits/wf.rs @@ -552,7 +552,6 @@ impl<'tcx> WfPredicates<'tcx> { | ty::Uint(..) | ty::Float(..) | ty::Error(_) - | ty::Str | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) | ty::Never diff --git a/compiler/rustc_traits/src/chalk/db.rs b/compiler/rustc_traits/src/chalk/db.rs index dbd5f13fe4e8b..da535d4622b60 100644 --- a/compiler/rustc_traits/src/chalk/db.rs +++ b/compiler/rustc_traits/src/chalk/db.rs @@ -436,7 +436,6 @@ impl<'tcx> chalk_solve::RustIrDatabase> for RustIrDatabase<'t OpaqueType(opaque_ty_id, ..), ) => def_id == opaque_ty_id.0, (&ty::FnDef(def_id, ..), FnDef(fn_def_id, ..)) => def_id == fn_def_id.0, - (&ty::Str, Str) => true, (&ty::Never, Never) => true, (&ty::Closure(def_id, ..), Closure(closure_id, _)) => def_id == closure_id.0, (&ty::Foreign(def_id), Foreign(foreign_def_id)) => def_id == foreign_def_id.0, diff --git a/compiler/rustc_traits/src/chalk/lowering.rs b/compiler/rustc_traits/src/chalk/lowering.rs index 7c9a014e2aba5..f7b625c26f005 100644 --- a/compiler/rustc_traits/src/chalk/lowering.rs +++ b/compiler/rustc_traits/src/chalk/lowering.rs @@ -301,7 +301,6 @@ impl<'tcx> LowerInto<'tcx, chalk_ir::Ty>> for Ty<'tcx> { chalk_ir::TyKind::Adt(chalk_ir::AdtId(def), substs.lower_into(interner)) } ty::Foreign(def_id) => chalk_ir::TyKind::Foreign(ForeignDefId(def_id)), - ty::Str => chalk_ir::TyKind::Str, ty::Array(ty, len) => { chalk_ir::TyKind::Array(ty.lower_into(interner), len.lower_into(interner)) } @@ -443,7 +442,7 @@ impl<'tcx> LowerInto<'tcx, Ty<'tcx>> for &chalk_ir::Ty> { ty.lower_into(interner), mutbl.lower_into(interner), ), - TyKind::Str => ty::Str, + TyKind::Str => unreachable!("TyKind::Str should never be returned by chalk"), TyKind::OpaqueType(opaque_ty, substitution) => ty::Alias( ty::Opaque, interner.tcx.mk_alias_ty(opaque_ty.0, substitution.lower_into(interner)), diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 8b7f8033bface..37f455e35f891 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -157,7 +157,6 @@ fn dtorck_constraint_for_ty<'tcx>( | ty::Int(_) | ty::Uint(_) | ty::Float(_) - | ty::Str | ty::Never | ty::Foreign(..) | ty::RawPtr(..) diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs index 2aeb255c1641c..0710a6043aa5c 100644 --- a/compiler/rustc_ty_utils/src/layout.rs +++ b/compiler/rustc_ty_utils/src/layout.rs @@ -176,7 +176,7 @@ fn layout_of_uncached<'tcx>( ty::Foreign(..) => { return Ok(tcx.intern_layout(LayoutS::scalar(cx, data_ptr))); } - ty::Slice(_) | ty::Str => scalar_unit(Int(dl.ptr_sized_integer(), false)), + ty::Slice(_) => scalar_unit(Int(dl.ptr_sized_integer(), false)), ty::Dynamic(..) => { let mut vtable = scalar_unit(Pointer(AddressSpace::DATA)); vtable.valid_range_mut().start = 1; @@ -241,14 +241,6 @@ fn layout_of_uncached<'tcx>( size: Size::ZERO, }) } - ty::Str => tcx.intern_layout(LayoutS { - variants: Variants::Single { index: VariantIdx::new(0) }, - fields: FieldsShape::Array { stride: Size::from_bytes(1), count: 0 }, - abi: Abi::Aggregate { sized: false }, - largest_niche: None, - align: dl.i8_align, - size: Size::ZERO, - }), // Odd unit types. ty::FnDef(..) => univariant(&[], &ReprOptions::default(), StructKind::AlwaysSized)?, diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 41e837e8b754e..96a1d605a88c6 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -17,8 +17,7 @@ fn sized_constraint_for_ty<'tcx>( Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..) | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![], - Str - | Dynamic(..) + Dynamic(..) | Slice(_) | Foreign(..) | Error(_) diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs index 61557fdc0eda4..fd5a085821aee 100644 --- a/compiler/rustc_type_ir/src/sty.rs +++ b/compiler/rustc_type_ir/src/sty.rs @@ -76,9 +76,6 @@ pub enum TyKind { /// An unsized FFI type that is opaque to Rust. Written as `extern type T`. Foreign(I::DefId), - /// The pointee of a string slice. Written as `str`. - Str, - /// An array with the given length. Written as `[T; N]`. Array(I::Ty, I::Const), @@ -248,7 +245,6 @@ const fn tykind_discriminant(value: &TyKind) -> usize { Float(_) => 4, Adt(_, _) => 5, Foreign(_) => 6, - Str => 7, Array(_, _) => 8, Slice(_) => 9, RawPtr(_) => 10, @@ -282,7 +278,6 @@ impl Clone for TyKind { Float(f) => Float(*f), Adt(d, s) => Adt(d.clone(), s.clone()), Foreign(d) => Foreign(d.clone()), - Str => Str, Array(t, c) => Array(t.clone(), c.clone()), Slice(t) => Slice(t.clone()), RawPtr(t) => RawPtr(t.clone()), @@ -346,7 +341,7 @@ impl PartialEq for TyKind { (Placeholder(a_p), Placeholder(b_p)) => a_p == b_p, (Infer(a_t), Infer(b_t)) => a_t == b_t, (Error(a_e), Error(b_e)) => a_e == b_e, - (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => true, + (Bool, Bool) | (Char, Char) | (Never, Never) => true, _ => { debug_assert!( tykind_discriminant(self) != tykind_discriminant(other), @@ -410,7 +405,7 @@ impl Ord for TyKind { (Placeholder(a_p), Placeholder(b_p)) => a_p.cmp(b_p), (Infer(a_t), Infer(b_t)) => a_t.cmp(b_t), (Error(a_e), Error(b_e)) => a_e.cmp(b_e), - (Bool, Bool) | (Char, Char) | (Str, Str) | (Never, Never) => Ordering::Equal, + (Bool, Bool) | (Char, Char) | (Never, Never) => Ordering::Equal, _ => { debug_assert!(false, "This branch must be unreachable, maybe the match is missing an arm? self = {self:?}, other = {other:?}"); Ordering::Equal @@ -481,7 +476,7 @@ impl hash::Hash for TyKind { Placeholder(p) => p.hash(state), Infer(t) => t.hash(state), Error(e) => e.hash(state), - Bool | Char | Str | Never => (), + Bool | Char | Never => (), } } } @@ -497,7 +492,6 @@ impl fmt::Debug for TyKind { Float(float) => f.debug_tuple_field1_finish("Float", float), Adt(d, s) => f.debug_tuple_field2_finish("Adt", d, s), Foreign(d) => f.debug_tuple_field1_finish("Foreign", d), - Str => f.write_str("Str"), Array(t, c) => f.debug_tuple_field2_finish("Array", t, c), Slice(t) => f.debug_tuple_field1_finish("Slice", t), RawPtr(t) => f.debug_tuple_field1_finish("RawPtr", t), @@ -567,7 +561,6 @@ where Foreign(def_id) => e.emit_enum_variant(disc, |e| { def_id.encode(e); }), - Str => e.emit_enum_variant(disc, |_| {}), Array(t, c) => e.emit_enum_variant(disc, |e| { t.encode(e); c.encode(e); @@ -674,7 +667,7 @@ where 4 => Float(Decodable::decode(d)), 5 => Adt(Decodable::decode(d), Decodable::decode(d)), 6 => Foreign(Decodable::decode(d)), - 7 => Str, + // 7: used to be Str, FIXME: move all these down 8 => Array(Decodable::decode(d), Decodable::decode(d)), 9 => Slice(Decodable::decode(d)), 10 => RawPtr(Decodable::decode(d)), @@ -755,7 +748,6 @@ where Foreign(def_id) => { def_id.hash_stable(__hcx, __hasher); } - Str => {} Array(t, c) => { t.hash_stable(__hcx, __hasher); c.hash_stable(__hcx, __hasher); diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index ab2f8520ecb33..4a8300e86d253 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -76,6 +76,15 @@ use iter::MatchIndicesInternal; use iter::SplitInternal; use iter::{MatchesInternal, SplitNInternal}; +/// strang +#[cfg(not(bootstrap))] +#[allow(non_camel_case_types)] +#[unstable(feature = "the_str_type_itself_in_all_its_glory", issue = "none")] +#[rustc_has_incoherent_inherent_impls] +#[lang = "str"] +#[repr(transparent)] +pub struct str([u8]); + #[inline(never)] #[cold] #[track_caller] diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index d3ed811b1575b..d204d055b6067 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -37,6 +37,14 @@ impl PartialEq for str { #[stable(feature = "rust1", since = "1.0.0")] impl Eq for str {} +#[cfg(not(bootstrap))] +#[stable(feature = "str_type_impls", since = "CURRENT_VERSION")] +impl crate::marker::StructuralPartialEq for str {} + +#[cfg(not(bootstrap))] +#[stable(feature = "str_type_impls", since = "CURRENT_VERSION")] +impl crate::marker::StructuralEq for str {} + /// Implements comparison operations on strings. /// /// Strings are compared [lexicographically](Ord#lexicographical-comparison) by their byte values. This compares Unicode code diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs index aed0ad5d9b5a7..6ff7d5850e58f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs @@ -33,7 +33,7 @@ pub(super) fn check<'tcx>( if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && { let arg_type = cx.typeck_results().expr_ty(receiver); let base_type = arg_type.peel_refs(); - *base_type.kind() == ty::Str || is_type_lang_item(cx, base_type, hir::LangItem::String) + *base_type.is_str() || is_type_lang_item(cx, base_type, hir::LangItem::String) } { receiver } else { @@ -54,7 +54,7 @@ pub(super) fn check<'tcx>( return false; } if let ty::Ref(_, ty, ..) = arg_ty.kind() { - if *ty.kind() == ty::Str && can_be_static_str(cx, arg) { + if *ty.is_str() && can_be_static_str(cx, arg) { return false; } }; diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs index 1c031ad6acbaf..288ee0fcf93f4 100644 --- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs +++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs @@ -108,7 +108,7 @@ pub(super) fn check<'tcx>( if is_type_lang_item(cx, self_ty, hir::LangItem::String) { true } else { - *self_ty.kind() == ty::Str + *self_ty.is_str() } }; if_chain! { diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs index 4221c52d5cd79..4e64f849ed026 100644 --- a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs @@ -47,7 +47,7 @@ pub(super) fn check( for &(method, pos) in &PATTERN_METHODS { if_chain! { if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(receiver).kind(); - if *ty.kind() == ty::Str; + if *ty.is_str(); if method_name.as_str() == method && args.len() > pos; let arg = &args[pos]; let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs index f35d81cee8e97..4f4f9809658af 100644 --- a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs +++ b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs @@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr if let Some(arglists) = method_chain_args(arg, &["chars"]) { let target = &arglists[0].0; let self_ty = cx.typeck_results().expr_ty(target).peel_refs(); - let ref_str = if *self_ty.kind() == ty::Str { + let ref_str = if *self_ty.is_str() { if matches!(target.kind, hir::ExprKind::Index(..)) { "&" } else { diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index bc18cad6d381b..602dac8ea30f6 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -407,7 +407,7 @@ impl<'tcx> LateLintPass<'tcx> for StrToString { if path.ident.name == sym::to_string; let ty = cx.typeck_results().expr_ty(self_arg); if let ty::Ref(_, ty, ..) = ty.kind(); - if *ty.kind() == ty::Str; + if *ty.is_str(); then { span_lint_and_help( cx, diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index c48d27b05f045..a32e90ff871d4 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -346,7 +346,7 @@ pub fn is_non_aggregate_primitive_type(ty: Ty<'_>) -> bool { pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool { match *ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => true, - ty::Ref(_, inner, _) if *inner.kind() == ty::Str => true, + ty::Ref(_, inner, _) if *inner.is_str() => true, ty::Array(inner_type, _) | ty::Slice(inner_type) => is_recursively_primitive_type(inner_type), ty::Tuple(inner_types) => inner_types.iter().all(is_recursively_primitive_type), _ => false, diff --git a/tests/ui/async-await/issue-72590-type-error-sized.stderr b/tests/ui/async-await/issue-72590-type-error-sized.stderr index 778423578e169..dfc240d5f92d0 100644 --- a/tests/ui/async-await/issue-72590-type-error-sized.stderr +++ b/tests/ui/async-await/issue-72590-type-error-sized.stderr @@ -10,13 +10,13 @@ error[E0412]: cannot find type `Missing` in this scope LL | test: Missing | ^^^^^^^ not found in this scope -error[E0277]: the size for values of type `str` cannot be known at compilation time +error[E0277]: the size for values of type `[u8]` cannot be known at compilation time --> $DIR/issue-72590-type-error-sized.rs:15:19 | LL | async fn frob(self) {} | ^^^^ doesn't have a size known at compile-time | - = help: within `Foo`, the trait `Sized` is not implemented for `str` + = help: within `Foo`, the trait `Sized` is not implemented for `[u8]` note: required because it appears within the type `Foo` --> $DIR/issue-72590-type-error-sized.rs:5:8 | diff --git a/tests/ui/coherence/coherence-negative-impls-copy-bad.stderr b/tests/ui/coherence/coherence-negative-impls-copy-bad.stderr index 2295d6315d1c2..26895b99187c2 100644 --- a/tests/ui/coherence/coherence-negative-impls-copy-bad.stderr +++ b/tests/ui/coherence/coherence-negative-impls-copy-bad.stderr @@ -1,4 +1,4 @@ -error[E0117]: only traits defined in the current crate can be implemented for arbitrary types +error[E0117]: only traits defined in the current crate can be implemented for types defined outside of the crate --> $DIR/coherence-negative-impls-copy-bad.rs:4:1 | LL | impl !Copy for str {} diff --git a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr index e4c5e62f6bd3a..f4f439fd37db2 100644 --- a/tests/ui/consts/const-eval/raw-bytes.64bit.stderr +++ b/tests/ui/consts/const-eval/raw-bytes.64bit.stderr @@ -266,7 +266,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/raw-bytes.rs:144:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered uninitialized data in `str` + | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0[0]: encountered uninitialized bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { @@ -277,7 +277,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/raw-bytes.rs:146:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered uninitialized data in `str` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0.0[0]: encountered uninitialized bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: 16, align: 8) { diff --git a/tests/ui/consts/const-eval/ub-wide-ptr.stderr b/tests/ui/consts/const-eval/ub-wide-ptr.stderr index f38e7916b7553..ec256c1ca0687 100644 --- a/tests/ui/consts/const-eval/ub-wide-ptr.stderr +++ b/tests/ui/consts/const-eval/ub-wide-ptr.stderr @@ -53,7 +53,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:52:1 | LL | const STR_NO_INIT: &str = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; - | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at .: encountered uninitialized data in `str` + | ^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0[0]: encountered uninitialized bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { @@ -64,7 +64,7 @@ error[E0080]: it is undefined behavior to use this value --> $DIR/ub-wide-ptr.rs:55:1 | LL | const MYSTR_NO_INIT: &MyStr = unsafe { mem::transmute::<&[_], _>(&[MaybeUninit:: { uninit: () }]) }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0: encountered uninitialized data in `str` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ constructing invalid value at ..0.0[0]: encountered uninitialized bytes | = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rustc repository if you believe it should not be considered undefined behavior. = note: the raw bytes of the constant (size: $SIZE, align: $ALIGN) { diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr index 8d4529526e370..c6bbaa158bd3c 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.stderr @@ -1,4 +1,4 @@ -error: use of deprecated associated function `core::str::::trim_left`: superseded by `trim_start` +error: use of deprecated associated function `str::trim_left`: superseded by `trim_start` --> $DIR/issue-84637-deprecated-associated-function.rs:6:21 | LL | let _foo = str::trim_left(" aoeu"); @@ -14,7 +14,7 @@ help: replace the use of the deprecated associated function LL | let _foo = str::trim_start(" aoeu"); | ~~~~~~~~~~ -error: use of deprecated associated function `core::str::::trim_left`: superseded by `trim_start` +error: use of deprecated associated function `str::trim_left`: superseded by `trim_start` --> $DIR/issue-84637-deprecated-associated-function.rs:8:26 | LL | let _bar = " aoeu".trim_left(); diff --git a/tests/ui/kinds-of-primitive-impl.stderr b/tests/ui/kinds-of-primitive-impl.stderr index f4dbd1c40e818..09cd6efd31b7f 100644 --- a/tests/ui/kinds-of-primitive-impl.stderr +++ b/tests/ui/kinds-of-primitive-impl.stderr @@ -6,13 +6,17 @@ LL | impl u8 { | = help: consider using an extension trait instead -error[E0390]: cannot define inherent `impl` for primitive types - --> $DIR/kinds-of-primitive-impl.rs:6:6 +error[E0116]: cannot define inherent `impl` for a type outside of the crate where the type is defined + --> $DIR/kinds-of-primitive-impl.rs:6:1 | -LL | impl str { - | ^^^ +LL | / impl str { +LL | | +LL | | fn foo() {} +LL | | fn bar(self) {} +LL | | } + | |_^ impl for type defined outside of crate. | - = help: consider using an extension trait instead + = note: define and implement a trait or new type instead error[E0390]: cannot define inherent `impl` for primitive types --> $DIR/kinds-of-primitive-impl.rs:12:6 @@ -33,4 +37,5 @@ LL | impl &MyType { error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0390`. +Some errors have detailed explanations: E0116, E0390. +For more information about an error, try `rustc --explain E0116`. diff --git a/tests/ui/pattern/usefulness/issue-30240.stderr b/tests/ui/pattern/usefulness/issue-30240.stderr index 759fdeafe4eb5..4013351778196 100644 --- a/tests/ui/pattern/usefulness/issue-30240.stderr +++ b/tests/ui/pattern/usefulness/issue-30240.stderr @@ -4,6 +4,8 @@ error[E0004]: non-exhaustive patterns: `&_` not covered LL | match "world" { | ^^^^^^^ pattern `&_` not covered | +note: `str` defined here + --> $SRC_DIR/core/src/str/mod.rs:LL:COL = note: the matched value is of type `&str` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | @@ -17,6 +19,8 @@ error[E0004]: non-exhaustive patterns: `&_` not covered LL | match "world" { | ^^^^^^^ pattern `&_` not covered | +note: `str` defined here + --> $SRC_DIR/core/src/str/mod.rs:LL:COL = note: the matched value is of type `&str` help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown | diff --git a/tests/ui/print_type_sizes/niche-filling.stdout b/tests/ui/print_type_sizes/niche-filling.stdout index d1753c26ca83b..214bb8960fe98 100644 --- a/tests/ui/print_type_sizes/niche-filling.stdout +++ b/tests/ui/print_type_sizes/niche-filling.stdout @@ -110,3 +110,5 @@ print-type-size discriminant: 1 bytes print-type-size variant `Less`: 0 bytes print-type-size variant `Equal`: 0 bytes print-type-size variant `Greater`: 0 bytes +print-type-size type: `str`: 0 bytes, alignment: 1 bytes +print-type-size field `.0`: 0 bytes diff --git a/tests/ui/str/str-idx.stderr b/tests/ui/str/str-idx.stderr index cb1a6fcacfc9b..a2a1e6705334d 100644 --- a/tests/ui/str/str-idx.stderr +++ b/tests/ui/str/str-idx.stderr @@ -22,7 +22,7 @@ LL | let _ = s.get(4); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[T]>` is implemented for `usize` -note: required by a bound in `core::str::::get` +note: required by a bound in `str::get` --> $SRC_DIR/core/src/str/mod.rs:LL:COL error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -37,7 +37,7 @@ LL | let _ = s.get_unchecked(4); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[T]>` is implemented for `usize` -note: required by a bound in `core::str::::get_unchecked` +note: required by a bound in `str::get_unchecked` --> $SRC_DIR/core/src/str/mod.rs:LL:COL error[E0277]: the type `str` cannot be indexed by `char` diff --git a/tests/ui/str/str-mut-idx.stderr b/tests/ui/str/str-mut-idx.stderr index ca4b86ba3065b..0c1327ba5edc9 100644 --- a/tests/ui/str/str-mut-idx.stderr +++ b/tests/ui/str/str-mut-idx.stderr @@ -46,7 +46,7 @@ LL | s.get_mut(1); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[T]>` is implemented for `usize` -note: required by a bound in `core::str::::get_mut` +note: required by a bound in `str::get_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL error[E0277]: the type `str` cannot be indexed by `{integer}` @@ -61,7 +61,7 @@ LL | s.get_unchecked_mut(1); = note: you can use `.chars().nth()` or `.bytes().nth()` for more information, see chapter 8 in The Book: = help: the trait `SliceIndex<[T]>` is implemented for `usize` -note: required by a bound in `core::str::::get_unchecked_mut` +note: required by a bound in `str::get_unchecked_mut` --> $SRC_DIR/core/src/str/mod.rs:LL:COL error[E0277]: the type `str` cannot be indexed by `char` diff --git a/tests/ui/suggestions/issue-62843.stderr b/tests/ui/suggestions/issue-62843.stderr index b6e271de8076c..d0b817569ac6c 100644 --- a/tests/ui/suggestions/issue-62843.stderr +++ b/tests/ui/suggestions/issue-62843.stderr @@ -8,7 +8,7 @@ LL | println!("{:?}", line.find(pattern)); | = note: the trait bound `String: Pattern<'_>` is not satisfied = note: required for `String` to implement `Pattern<'_>` -note: required by a bound in `core::str::::find` +note: required by a bound in `str::find` --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider borrowing here | diff --git a/tests/ui/symbol-names/basic.legacy.stderr b/tests/ui/symbol-names/basic.legacy.stderr index fe490a6000d7b..71bebf9d55900 100644 --- a/tests/ui/symbol-names/basic.legacy.stderr +++ b/tests/ui/symbol-names/basic.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN5basic4main17he9f658e438f1cac0E) +error: symbol-name(_ZN5basic4main17h8ac158452a72e5c6E) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(basic::main::he9f658e438f1cac0) +error: demangling(basic::main::h8ac158452a72e5c6) --> $DIR/basic.rs:8:1 | LL | #[rustc_symbol_name] diff --git a/tests/ui/symbol-names/issue-60925.legacy.stderr b/tests/ui/symbol-names/issue-60925.legacy.stderr index 29b42f48d803a..4102f2915cbba 100644 --- a/tests/ui/symbol-names/issue-60925.legacy.stderr +++ b/tests/ui/symbol-names/issue-60925.legacy.stderr @@ -1,10 +1,10 @@ -error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h13209029be24b923E) +error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h31956c6f29014506E) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] | ^^^^^^^^^^^^^^^^^^^^ -error: demangling(issue_60925::foo::Foo::foo::h13209029be24b923) +error: demangling(issue_60925::foo::Foo::foo::h31956c6f29014506) --> $DIR/issue-60925.rs:21:9 | LL | #[rustc_symbol_name] diff --git a/tests/ui/traits/suggest-deferences/root-obligation.stderr b/tests/ui/traits/suggest-deferences/root-obligation.stderr index 1363fb8c47af8..deb50227cbbe6 100644 --- a/tests/ui/traits/suggest-deferences/root-obligation.stderr +++ b/tests/ui/traits/suggest-deferences/root-obligation.stderr @@ -9,7 +9,7 @@ LL | .filter(|c| "aeiou".contains(c)) = help: the trait `Fn<(char,)>` is not implemented for `char` = note: required for `&char` to implement `FnOnce<(char,)>` = note: required for `&char` to implement `Pattern<'_>` -note: required by a bound in `core::str::::contains` +note: required by a bound in `str::contains` --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider dereferencing here | From 46e715cd7a6ff8d0086880ee23ccbdfbc15719d3 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 Feb 2023 22:17:18 +0000 Subject: [PATCH 3/4] Fix a bunch of fallout issues with str being a struct --- .../src/debuginfo/type_names.rs | 1 + .../src/const_eval/valtrees.rs | 15 ------- .../rustc_const_eval/src/util/type_name.rs | 3 ++ .../rustc_middle/src/ty/consts/valtree.rs | 7 +++- compiler/rustc_middle/src/ty/sty.rs | 1 - compiler/rustc_middle/src/ty/util.rs | 16 ++++++- compiler/rustc_mir_build/src/thir/constant.rs | 4 +- .../src/thir/pattern/check_match.rs | 2 +- .../src/typeid/typeid_itanium_cxx_abi.rs | 1 + .../src/traits/select/mod.rs | 9 +++- library/core/src/str/mod.rs | 5 +-- library/core/src/str/traits.rs | 4 +- src/librustdoc/clean/mod.rs | 2 +- .../passes/collect_intra_doc_links.rs | 42 +++++++++---------- .../src/methods/search_is_some.rs | 2 +- .../src/methods/single_char_pattern.rs | 2 +- .../src/methods/string_extend_chars.rs | 2 +- src/tools/clippy/clippy_lints/src/strings.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 2 +- tests/assembly/asm/aarch64-modifiers.rs | 2 + tests/assembly/asm/aarch64-types.rs | 2 + tests/assembly/asm/arm-modifiers.rs | 2 + tests/assembly/asm/arm-types.rs | 2 + tests/assembly/asm/avr-modifiers.rs | 2 + tests/assembly/asm/avr-types.rs | 2 + tests/assembly/asm/bpf-types.rs | 2 + tests/assembly/asm/hexagon-types.rs | 2 + tests/assembly/asm/mips-types.rs | 2 + tests/assembly/asm/msp430-types.rs | 2 + tests/assembly/asm/nvptx-types.rs | 2 + tests/assembly/asm/powerpc-types.rs | 2 + tests/assembly/asm/riscv-types.rs | 2 + tests/assembly/asm/s390x-types.rs | 2 + tests/assembly/asm/wasm-types.rs | 2 + tests/assembly/asm/x86-modifiers.rs | 2 + tests/assembly/asm/x86-types.rs | 2 + .../some-abis-do-extend-params-to-32-bits.rs | 8 +++- ..._line_doc_comment_2.DeduplicateBlocks.diff | 4 +- ...84637-deprecated-associated-function.fixed | 4 +- ...ue-84637-deprecated-associated-function.rs | 4 +- tests/ui/kinds-of-primitive-impl.rs | 2 +- tests/ui/stdlib-unit-tests/issue-21058.rs | 2 +- tests/ui/suggestions/issue-104961.stderr | 4 +- 43 files changed, 116 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs index 7e10f8e586f6b..1be7134326e78 100644 --- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs +++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs @@ -59,6 +59,7 @@ fn push_debuginfo_type_name<'tcx>( match *t.kind() { ty::Bool => output.push_str("bool"), ty::Char => output.push_str("char"), + // FIXME(str): Do we need this? Or should we really just treat it like an ADT? ty::Adt(def, _) if def.is_str() => { if cpp_like_debuginfo { output.push_str("str$") diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs index 4f7bb280a0377..eec96e09d1757 100644 --- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs +++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs @@ -115,11 +115,6 @@ pub(crate) fn const_to_valtree_inner<'tcx>( slice_branches(ecx, place, num_nodes) } - // FIXME(str): Do we need this? - ty::Adt(def, _) if def.is_str() => { - slice_branches(ecx, place, num_nodes) - } - // Trait objects are not allowed in type level constants, as we have no concept for // resolving their backing type, even if we can do that at const eval time. We may // hypothetically be able to allow `dyn StructuralEq` trait objects in the future, @@ -356,15 +351,6 @@ fn valtree_into_mplace<'tcx>( len_scalar, ) } - ty::Adt(def, _) if def.is_str() => { - let len = valtree.unwrap_branch().len(); - let len_scalar = Scalar::from_machine_usize(len as u64, &tcx); - - Immediate::ScalarPair( - Scalar::from_maybe_pointer((*pointee_place).ptr, &tcx), - len_scalar, - ) - } _ => pointee_place.to_ref(&tcx), }; debug!(?imm); @@ -399,7 +385,6 @@ fn valtree_into_mplace<'tcx>( debug!(?i, ?inner_valtree); let mut place_inner = match ty.kind() { - ty::Adt(def, _) if def.is_str() => ecx.mplace_index(&place, i as u64).unwrap(), ty::Slice(_) => ecx.mplace_index(&place, i as u64).unwrap(), _ if !ty.is_sized(*ecx.tcx, ty::ParamEnv::empty()) && i == branches.len() - 1 => diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs index 0cc73e9aa87c5..01a9ae052d589 100644 --- a/compiler/rustc_const_eval/src/util/type_name.rs +++ b/compiler/rustc_const_eval/src/util/type_name.rs @@ -48,6 +48,9 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> { | ty::Tuple(_) | ty::Dynamic(_, _, _) => self.pretty_print_type(ty), + // FIXME(str): We could accept that it's an ADt, and print this like `std::str::Str`? + ty::Adt(def, _) if def.is_str() => self.pretty_print_type(ty), + // Placeholders (all printed as `_` to uniformize them). ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => { write!(self, "_")?; diff --git a/compiler/rustc_middle/src/ty/consts/valtree.rs b/compiler/rustc_middle/src/ty/consts/valtree.rs index 9db534794cc8b..8e648956b7a65 100644 --- a/compiler/rustc_middle/src/ty/consts/valtree.rs +++ b/compiler/rustc_middle/src/ty/consts/valtree.rs @@ -84,11 +84,14 @@ impl<'tcx> ValTree<'tcx> { /// Get the values inside the ValTree as a slice of bytes. This only works for /// constants with types &str, &[u8], or [u8; _]. - pub fn try_to_raw_bytes(self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx [u8]> { + pub fn try_to_raw_bytes(mut self, tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<&'tcx [u8]> { match ty.kind() { ty::Ref(_, inner_ty, _) => match inner_ty.kind() { // `&str` can be interpreted as raw bytes - ty::Adt(def, _) if def.is_str() => {} + ty::Adt(def, _) if def.is_str() => { + // we need to unwrap one more layer of ADT to get to the `[u8]` + self = self.unwrap_branch()[0]; + } // `&[u8]` can be interpreted as raw bytes ty::Slice(slice_ty) if *slice_ty == tcx.types.u8 => {} // other `&_` can't be interpreted as raw bytes diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 3030b669993a9..3c2f883b1b3b9 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1854,7 +1854,6 @@ impl<'tcx> Ty<'tcx> { } } - // FIXME(str): Remove tcx from this pub fn sequence_element_type(self) -> Ty<'tcx> { match self.kind() { Array(ty, _) | Slice(ty) => *ty, diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index f8b7a79dc8a42..ae16f53a3ac08 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -955,8 +955,11 @@ impl<'tcx> Ty<'tcx> { | ty::FnDef(..) | ty::Error(_) | ty::FnPtr(_) => true, - // FIXME(str): make sure this is true :^) + + // This should be encoded somewhere as part of the "contract" + // for a valid `core::str::Str` implementation ty::Adt(def, _) if def.is_str() => true, + ty::Tuple(fields) => fields.iter().all(Self::is_trivially_freeze), ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_freeze(), ty::Adt(..) @@ -996,8 +999,11 @@ impl<'tcx> Ty<'tcx> { | ty::FnDef(..) | ty::Error(_) | ty::FnPtr(_) => true, - // FIXME(str): make sure this is true :^) + + // This should be encoded somewhere as part of the "contract" + // for a valid `core::str::Str` implementation ty::Adt(def, _) if def.is_str() => true, + ty::Tuple(fields) => fields.iter().all(Self::is_trivially_unpin), ty::Slice(elem_ty) | ty::Array(elem_ty, _) => elem_ty.is_trivially_unpin(), ty::Adt(..) @@ -1238,6 +1244,8 @@ pub fn needs_drop_components<'tcx>( | ty::RawPtr(_) | ty::Ref(..) => Ok(SmallVec::new()), + // This should be encoded somewhere as part of the "contract" + // for a valid `core::str::Str` implementation ty::Adt(def, _) if def.is_str() => Ok(SmallVec::new()), // Foreign types can never have destructors. @@ -1295,6 +1303,10 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool { | ty::Never | ty::Foreign(_) => true, + // This should be encoded somewhere as part of the "contract" + // for a valid `core::str::Str` implementation + ty::Adt(def, _) if def.is_str() => true, + ty::Alias(..) | ty::Dynamic(..) | ty::Error(_) diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 57ae6a3652df5..bccfa9846ac1d 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -31,7 +31,9 @@ pub(crate) fn lit_to_const<'tcx>( let valtree = match (lit, &ty.kind()) { (ast::LitKind::Str(s, _), ty::Ref(_, inner_ty, _)) if inner_ty.is_str() => { let str_bytes = s.as_str().as_bytes(); - ty::ValTree::from_raw_bytes(tcx, str_bytes) + ty::ValTree::Branch( + tcx.arena.alloc_slice(&[ty::ValTree::from_raw_bytes(tcx, str_bytes)]), + ) } (ast::LitKind::ByteStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Slice(_)) => diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs index 2640ca56b00e9..bd0613afbe7fa 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs @@ -812,7 +812,7 @@ fn adt_defined_here<'p, 'tcx>( witnesses: &[DeconstructedPat<'p, 'tcx>], ) { let ty = ty.peel_refs(); - if let ty::Adt(def, _) = ty.kind() { + if let ty::Adt(def, _) = ty.kind() && !def.is_str() { let mut spans = vec![]; if witnesses.len() < 5 { for sp in maybe_point_at_variant(cx, *def, witnesses.iter()) { diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs index ad6085227dd3f..bbebd9df6caa7 100644 --- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs +++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs @@ -481,6 +481,7 @@ fn encode_ty<'tcx>( typeid.push_str(&s); } + // FIXME(str): Do we need this? ty::Adt(def, _) if def.is_str() => { // u3str as vendor extended type let mut s = String::from("u3str"); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 8c7d0df5675d0..5a8db03b65c22 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -2080,8 +2080,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { } ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None, - - // FIXME(str): We special case this impl for diagnostics reasons. + + // We special case this impl for diagnostics reasons, + // otherwise we'll try explaining that `str` isn't Sized + // because `[u8]` isn't Sized. ty::Adt(def, _) if def.is_str() => None, ty::Tuple(tys) => Where( @@ -2149,6 +2151,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // FIXME(str): We special case this impl for diagnostics reasons. ty::Adt(def, _) if def.is_str() => None, + // FIXME(str): We special case this impl for diagnostics reasons. + ty::Adt(def, _) if def.is_str() => None, + ty::Tuple(tys) => { // (*) binder moved here Where(obligation.predicate.rebind(tys.iter().collect())) diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs index 4a8300e86d253..3f7de7a7c51a2 100644 --- a/library/core/src/str/mod.rs +++ b/library/core/src/str/mod.rs @@ -76,14 +76,13 @@ use iter::MatchIndicesInternal; use iter::SplitInternal; use iter::{MatchesInternal, SplitNInternal}; -/// strang +/// Hello I am a str #[cfg(not(bootstrap))] -#[allow(non_camel_case_types)] #[unstable(feature = "the_str_type_itself_in_all_its_glory", issue = "none")] #[rustc_has_incoherent_inherent_impls] #[lang = "str"] #[repr(transparent)] -pub struct str([u8]); +pub struct Str([u8]); #[inline(never)] #[cold] diff --git a/library/core/src/str/traits.rs b/library/core/src/str/traits.rs index d204d055b6067..56a3320edbfbd 100644 --- a/library/core/src/str/traits.rs +++ b/library/core/src/str/traits.rs @@ -38,11 +38,11 @@ impl PartialEq for str { impl Eq for str {} #[cfg(not(bootstrap))] -#[stable(feature = "str_type_impls", since = "CURRENT_VERSION")] +#[stable(feature = "str_type_impls", since = "1.68.0")] impl crate::marker::StructuralPartialEq for str {} #[cfg(not(bootstrap))] -#[stable(feature = "str_type_impls", since = "CURRENT_VERSION")] +#[stable(feature = "str_type_impls", since = "1.68.0")] impl crate::marker::StructuralEq for str {} /// Implements comparison operations on strings. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d497f7ea67976..c6c730424d442 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1699,7 +1699,7 @@ pub(crate) fn clean_middle_ty<'tcx>( ty::Int(int_ty) => Primitive(int_ty.into()), ty::Uint(uint_ty) => Primitive(uint_ty.into()), ty::Float(float_ty) => Primitive(float_ty.into()), - ty::Str => Primitive(PrimitiveType::Str), + ty::Adt(def, _) if def.is_str() => Primitive(PrimitiveType::Str), ty::Slice(ty) => Slice(Box::new(clean_middle_ty(bound_ty.rebind(ty), cx, None))), ty::Array(ty, mut n) => { n = n.eval(cx.tcx, ty::ParamEnv::reveal_all()); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 692adcf0a8091..fc08357b6012a 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -478,7 +478,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { ty::Int(ity) => Res::Primitive(ity.into()), ty::Uint(uty) => Res::Primitive(uty.into()), ty::Float(fty) => Res::Primitive(fty.into()), - ty::Str => Res::Primitive(Str), + ty::Adt(def, _) if def.is_str() => Res::Primitive(Str), ty::Tuple(tys) if tys.is_empty() => Res::Primitive(Unit), ty::Tuple(_) => Res::Primitive(Tuple), ty::Array(..) => Res::Primitive(Array), @@ -515,27 +515,27 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { // FIXME: Only simple types are supported here, see if we can support // other types such as Tuple, Array, Slice, etc. // See https://github.com/rust-lang/rust/issues/90703#issuecomment-1004263455 - Some(tcx.mk_ty(match prim { - Bool => ty::Bool, - Str => ty::Str, - Char => ty::Char, - Never => ty::Never, - I8 => ty::Int(ty::IntTy::I8), - I16 => ty::Int(ty::IntTy::I16), - I32 => ty::Int(ty::IntTy::I32), - I64 => ty::Int(ty::IntTy::I64), - I128 => ty::Int(ty::IntTy::I128), - Isize => ty::Int(ty::IntTy::Isize), - F32 => ty::Float(ty::FloatTy::F32), - F64 => ty::Float(ty::FloatTy::F64), - U8 => ty::Uint(ty::UintTy::U8), - U16 => ty::Uint(ty::UintTy::U16), - U32 => ty::Uint(ty::UintTy::U32), - U64 => ty::Uint(ty::UintTy::U64), - U128 => ty::Uint(ty::UintTy::U128), - Usize => ty::Uint(ty::UintTy::Usize), + Some(match prim { + Bool => tcx.types.bool, + Char => tcx.types.char, + Never => tcx.types.never, + I8 => tcx.types.i8, + I16 => tcx.types.i16, + I32 => tcx.types.i32, + I64 => tcx.types.i64, + I128 => tcx.types.i128, + Isize => tcx.types.isize, + F32 => tcx.types.f32, + F64 => tcx.types.f64, + U8 => tcx.types.u8, + U16 => tcx.types.u16, + U32 => tcx.types.u32, + U64 => tcx.types.u64, + U128 => tcx.types.u128, + Usize => tcx.types.usize, + Str => tcx.mk_str(), _ => return None, - })) + }) } /// Resolve an associated item, returning its containing page's `Res` diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs index 288ee0fcf93f4..ef545380578ec 100644 --- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs +++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs @@ -108,7 +108,7 @@ pub(super) fn check<'tcx>( if is_type_lang_item(cx, self_ty, hir::LangItem::String) { true } else { - *self_ty.is_str() + self_ty.is_str() } }; if_chain! { diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs index 4e64f849ed026..4d704ec39ebb1 100644 --- a/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs +++ b/src/tools/clippy/clippy_lints/src/methods/single_char_pattern.rs @@ -47,7 +47,7 @@ pub(super) fn check( for &(method, pos) in &PATTERN_METHODS { if_chain! { if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty_adjusted(receiver).kind(); - if *ty.is_str(); + if ty.is_str(); if method_name.as_str() == method && args.len() > pos; let arg = &args[pos]; let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs index 4f4f9809658af..685ee93ffd857 100644 --- a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs +++ b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs @@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr if let Some(arglists) = method_chain_args(arg, &["chars"]) { let target = &arglists[0].0; let self_ty = cx.typeck_results().expr_ty(target).peel_refs(); - let ref_str = if *self_ty.is_str() { + let ref_str = if self_ty.is_str() { if matches!(target.kind, hir::ExprKind::Index(..)) { "&" } else { diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index 602dac8ea30f6..fabf2ad815034 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -407,7 +407,7 @@ impl<'tcx> LateLintPass<'tcx> for StrToString { if path.ident.name == sym::to_string; let ty = cx.typeck_results().expr_ty(self_arg); if let ty::Ref(_, ty, ..) = ty.kind(); - if *ty.is_str(); + if ty.is_str(); then { span_lint_and_help( cx, diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index a32e90ff871d4..f293a7a3baeeb 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -346,7 +346,7 @@ pub fn is_non_aggregate_primitive_type(ty: Ty<'_>) -> bool { pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool { match *ty.kind() { ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => true, - ty::Ref(_, inner, _) if *inner.is_str() => true, + ty::Ref(_, inner, _) if inner.is_str() => true, ty::Array(inner_type, _) | ty::Slice(inner_type) => is_recursively_primitive_type(inner_type), ty::Tuple(inner_types) => inner_types.iter().all(is_recursively_primitive_type), _ => false, diff --git a/tests/assembly/asm/aarch64-modifiers.rs b/tests/assembly/asm/aarch64-modifiers.rs index 5196aa9fa1759..14186acdd54cb 100644 --- a/tests/assembly/asm/aarch64-modifiers.rs +++ b/tests/assembly/asm/aarch64-modifiers.rs @@ -21,6 +21,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); impl Copy for i32 {} diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs index 66c39a48c6e1d..9de3d3c937bfb 100644 --- a/tests/assembly/asm/aarch64-types.rs +++ b/tests/assembly/asm/aarch64-types.rs @@ -24,6 +24,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *mut u8; diff --git a/tests/assembly/asm/arm-modifiers.rs b/tests/assembly/asm/arm-modifiers.rs index 88ffeaecfecb6..23d4555cd9742 100644 --- a/tests/assembly/asm/arm-modifiers.rs +++ b/tests/assembly/asm/arm-modifiers.rs @@ -26,6 +26,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); #[repr(simd)] pub struct f32x4(f32, f32, f32, f32); diff --git a/tests/assembly/asm/arm-types.rs b/tests/assembly/asm/arm-types.rs index b22a26ce36f14..e427df4fae928 100644 --- a/tests/assembly/asm/arm-types.rs +++ b/tests/assembly/asm/arm-types.rs @@ -25,6 +25,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *mut u8; diff --git a/tests/assembly/asm/avr-modifiers.rs b/tests/assembly/asm/avr-modifiers.rs index ffdc8f2e351dd..fe9b52438b98a 100644 --- a/tests/assembly/asm/avr-modifiers.rs +++ b/tests/assembly/asm/avr-modifiers.rs @@ -20,6 +20,8 @@ macro_rules! concat { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const u64; diff --git a/tests/assembly/asm/avr-types.rs b/tests/assembly/asm/avr-types.rs index b2d11a8826f6b..6dc9371a7a0c6 100644 --- a/tests/assembly/asm/avr-types.rs +++ b/tests/assembly/asm/avr-types.rs @@ -20,6 +20,8 @@ macro_rules! concat { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const u64; diff --git a/tests/assembly/asm/bpf-types.rs b/tests/assembly/asm/bpf-types.rs index e177b8d0dbe50..a97b02531479a 100644 --- a/tests/assembly/asm/bpf-types.rs +++ b/tests/assembly/asm/bpf-types.rs @@ -24,6 +24,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const u64; diff --git a/tests/assembly/asm/hexagon-types.rs b/tests/assembly/asm/hexagon-types.rs index af16faedbc4a2..686f58761b75a 100644 --- a/tests/assembly/asm/hexagon-types.rs +++ b/tests/assembly/asm/hexagon-types.rs @@ -24,6 +24,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const i32; diff --git a/tests/assembly/asm/mips-types.rs b/tests/assembly/asm/mips-types.rs index 6aa28b062db8a..bdcdda59c8974 100644 --- a/tests/assembly/asm/mips-types.rs +++ b/tests/assembly/asm/mips-types.rs @@ -27,6 +27,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const i32; diff --git a/tests/assembly/asm/msp430-types.rs b/tests/assembly/asm/msp430-types.rs index 2c73b3b098de4..8b6f65e2f8b80 100644 --- a/tests/assembly/asm/msp430-types.rs +++ b/tests/assembly/asm/msp430-types.rs @@ -20,6 +20,8 @@ macro_rules! concat { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const i16; diff --git a/tests/assembly/asm/nvptx-types.rs b/tests/assembly/asm/nvptx-types.rs index c319946b5f5c1..971c3ed658568 100644 --- a/tests/assembly/asm/nvptx-types.rs +++ b/tests/assembly/asm/nvptx-types.rs @@ -19,6 +19,8 @@ macro_rules! concat { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *mut u8; diff --git a/tests/assembly/asm/powerpc-types.rs b/tests/assembly/asm/powerpc-types.rs index e27b005206835..7e825ffd41f5f 100644 --- a/tests/assembly/asm/powerpc-types.rs +++ b/tests/assembly/asm/powerpc-types.rs @@ -27,6 +27,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const i32; diff --git a/tests/assembly/asm/riscv-types.rs b/tests/assembly/asm/riscv-types.rs index f18ba294d0cff..cbb320ce2f2d1 100644 --- a/tests/assembly/asm/riscv-types.rs +++ b/tests/assembly/asm/riscv-types.rs @@ -28,6 +28,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *mut u8; diff --git a/tests/assembly/asm/s390x-types.rs b/tests/assembly/asm/s390x-types.rs index 2fb404dd9b280..619cadf6bafcd 100644 --- a/tests/assembly/asm/s390x-types.rs +++ b/tests/assembly/asm/s390x-types.rs @@ -25,6 +25,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *const i32; diff --git a/tests/assembly/asm/wasm-types.rs b/tests/assembly/asm/wasm-types.rs index 3b1ac1b455ad8..4e98cd56e3a1c 100644 --- a/tests/assembly/asm/wasm-types.rs +++ b/tests/assembly/asm/wasm-types.rs @@ -19,6 +19,8 @@ macro_rules! concat { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *mut u8; diff --git a/tests/assembly/asm/x86-modifiers.rs b/tests/assembly/asm/x86-modifiers.rs index 574fdf12cd040..b92bbb929c633 100644 --- a/tests/assembly/asm/x86-modifiers.rs +++ b/tests/assembly/asm/x86-modifiers.rs @@ -30,6 +30,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); impl Copy for i32 {} diff --git a/tests/assembly/asm/x86-types.rs b/tests/assembly/asm/x86-types.rs index 81be79cbaac18..08acee76721ba 100644 --- a/tests/assembly/asm/x86-types.rs +++ b/tests/assembly/asm/x86-types.rs @@ -29,6 +29,8 @@ macro_rules! stringify { trait Sized {} #[lang = "copy"] trait Copy {} +#[lang = "str"] +struct Str([u8]); type ptr = *mut u8; diff --git a/tests/codegen/some-abis-do-extend-params-to-32-bits.rs b/tests/codegen/some-abis-do-extend-params-to-32-bits.rs index 9f2d9d06524f0..6aacecff430b1 100644 --- a/tests/codegen/some-abis-do-extend-params-to-32-bits.rs +++ b/tests/codegen/some-abis-do-extend-params-to-32-bits.rs @@ -28,6 +28,9 @@ #[lang="freeze"] trait Freeze { } #[lang="copy"] trait Copy { } +#[lang = "str"] +struct Str([u8]); + // The patterns in this file are written in the style of a table to make the // uniformities and distinctions more apparent. // @@ -177,7 +180,8 @@ // riscv: i64 @c_ret_i64() #[no_mangle] pub extern "C" fn c_ret_i64() -> i64 { 0 } -const C_SOURCE_FILE: &'static str = r##" +/* Equivalent C source file: + #include #include #include @@ -201,4 +205,4 @@ int8_t c_ret_i8() { return 0; } int16_t c_ret_i16() { return 0; } int32_t c_ret_i32() { return 0; } int64_t c_ret_i64() { return 0; } -"##; +*/ diff --git a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff index 3b1f81175cbfc..5e89e36cbbb00 100644 --- a/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff +++ b/tests/mir-opt/deduplicate_blocks.is_line_doc_comment_2.DeduplicateBlocks.diff @@ -17,10 +17,10 @@ StorageLive(_2); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 StorageLive(_3); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 _3 = &(*_1); // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 - _2 = core::str::::as_bytes(move _3) -> bb1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 + _2 = str::as_bytes(move _3) -> bb1; // scope 0 at $DIR/deduplicate_blocks.rs:+1:11: +1:23 // mir::Constant // + span: $DIR/deduplicate_blocks.rs:5:13: 5:21 - // + literal: Const { ty: for<'a> fn(&'a str) -> &'a [u8] {core::str::::as_bytes}, val: Value() } + // + literal: Const { ty: for<'a> fn(&'a str) -> &'a [u8] {str::as_bytes}, val: Value() } } bb1: { diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed index 99a2b09614fd9..cacb648bf18bc 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.fixed @@ -3,7 +3,7 @@ #![deny(deprecated)] fn main() { - let _foo = str::trim_start(" aoeu"); //~ ERROR use of deprecated associated function `core::str::::trim_left`: superseded by `trim_start` [deprecated] + let _foo = str::trim_start(" aoeu"); //~ ERROR use of deprecated associated function `str::trim_left`: superseded by `trim_start` [deprecated] - let _bar = " aoeu".trim_start(); //~ ERROR use of deprecated associated function `core::str::::trim_left`: superseded by `trim_start` [deprecated] + let _bar = " aoeu".trim_start(); //~ ERROR use of deprecated associated function `str::trim_left`: superseded by `trim_start` [deprecated] } diff --git a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs index 62bf84aa3ea28..c874faea26cf0 100644 --- a/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs +++ b/tests/ui/deprecation/issue-84637-deprecated-associated-function.rs @@ -3,7 +3,7 @@ #![deny(deprecated)] fn main() { - let _foo = str::trim_left(" aoeu"); //~ ERROR use of deprecated associated function `core::str::::trim_left`: superseded by `trim_start` [deprecated] + let _foo = str::trim_left(" aoeu"); //~ ERROR use of deprecated associated function `str::trim_left`: superseded by `trim_start` [deprecated] - let _bar = " aoeu".trim_left(); //~ ERROR use of deprecated associated function `core::str::::trim_left`: superseded by `trim_start` [deprecated] + let _bar = " aoeu".trim_left(); //~ ERROR use of deprecated associated function `str::trim_left`: superseded by `trim_start` [deprecated] } diff --git a/tests/ui/kinds-of-primitive-impl.rs b/tests/ui/kinds-of-primitive-impl.rs index 6a067a9a36092..94e8bb73a5cbf 100644 --- a/tests/ui/kinds-of-primitive-impl.rs +++ b/tests/ui/kinds-of-primitive-impl.rs @@ -4,7 +4,7 @@ impl u8 { } impl str { -//~^ error: cannot define inherent `impl` for primitive types +//~^ error: cannot define inherent `impl` for a type outside of the crate where the type is defined fn foo() {} fn bar(self) {} } diff --git a/tests/ui/stdlib-unit-tests/issue-21058.rs b/tests/ui/stdlib-unit-tests/issue-21058.rs index 6facf0b2dd578..343c4f45174f5 100644 --- a/tests/ui/stdlib-unit-tests/issue-21058.rs +++ b/tests/ui/stdlib-unit-tests/issue-21058.rs @@ -18,7 +18,7 @@ macro_rules! check { fn main() { // type_name should support unsized types check!([u8], "[u8]"); - check!(str, "str"); + check!(str, "core::str::str"); check!(dyn Send, "dyn core::marker::Send"); check!(NT, "issue_21058::NT"); check!(DST, "issue_21058::DST"); diff --git a/tests/ui/suggestions/issue-104961.stderr b/tests/ui/suggestions/issue-104961.stderr index 8cec6a3f8270a..f22dd36250f27 100644 --- a/tests/ui/suggestions/issue-104961.stderr +++ b/tests/ui/suggestions/issue-104961.stderr @@ -8,7 +8,7 @@ LL | x.starts_with("hi".to_string() + " you") | = note: the trait bound `String: Pattern<'_>` is not satisfied = note: required for `String` to implement `Pattern<'_>` -note: required by a bound in `core::str::::starts_with` +note: required by a bound in `str::starts_with` --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider borrowing here | @@ -25,7 +25,7 @@ LL | x.starts_with("hi".to_string()) | = note: the trait bound `String: Pattern<'_>` is not satisfied = note: required for `String` to implement `Pattern<'_>` -note: required by a bound in `core::str::::starts_with` +note: required by a bound in `str::starts_with` --> $SRC_DIR/core/src/str/mod.rs:LL:COL help: consider borrowing here | From 0ff0260e1c02c5734b3f133bfcef9d2c75e8f474 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 11 Feb 2023 22:34:11 +0000 Subject: [PATCH 4/4] Appease clippy, rustdoc, codegen_cranelift and codegen_gcc --- compiler/rustc_codegen_cranelift/src/unsize.rs | 2 +- compiler/rustc_codegen_cranelift/src/value_and_place.rs | 2 +- compiler/rustc_codegen_gcc/src/type_of.rs | 2 +- src/tools/clippy/clippy_lints/src/dereference.rs | 2 +- src/tools/clippy/clippy_lints/src/format.rs | 3 +-- src/tools/clippy/clippy_lints/src/functions/must_use.rs | 2 +- src/tools/clippy/clippy_lints/src/len_zero.rs | 2 +- .../clippy_lints/src/matches/match_str_case_mismatch.rs | 4 ++-- src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs | 4 ++-- src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs | 4 ++-- .../clippy/clippy_lints/src/methods/inefficient_to_string.rs | 2 +- src/tools/clippy/clippy_lints/src/methods/search_is_some.rs | 1 - .../clippy/clippy_lints/src/methods/string_extend_chars.rs | 1 - .../clippy/clippy_lints/src/methods/unnecessary_to_owned.rs | 4 ++-- src/tools/clippy/clippy_lints/src/ptr.rs | 2 +- src/tools/clippy/clippy_lints/src/strings.rs | 2 +- .../clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs | 3 ++- src/tools/clippy/clippy_utils/src/consts.rs | 2 +- src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs | 2 +- src/tools/clippy/clippy_utils/src/ty.rs | 4 +++- 20 files changed, 25 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs index 9c88f7dbcda33..20509be8ea2a1 100644 --- a/compiler/rustc_codegen_cranelift/src/unsize.rs +++ b/compiler/rustc_codegen_cranelift/src/unsize.rs @@ -198,7 +198,7 @@ pub(crate) fn size_and_align_of_dst<'tcx>( // load size/align from vtable (crate::vtable::size_of_obj(fx, info), crate::vtable::min_align_of_obj(fx, info)) } - ty::Slice(_) | ty::Str => { + ty::Slice(_) => { let unit = layout.field(fx, 0); // The info in this case is the length of the str, so the size is that // times the unit size. diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs index 320eecaee008e..21b8a3e62f8ae 100644 --- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs +++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs @@ -23,7 +23,7 @@ fn codegen_field<'tcx>( return simple(fx); } match field_layout.ty.kind() { - ty::Slice(..) | ty::Str | ty::Foreign(..) => simple(fx), + ty::Slice(..) | ty::Foreign(..) => simple(fx), ty::Adt(def, _) if def.repr().packed() => { assert_eq!(layout.align.abi.bytes(), 1); simple(fx) diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs index 1326af670cde4..ef9a629860d07 100644 --- a/compiler/rustc_codegen_gcc/src/type_of.rs +++ b/compiler/rustc_codegen_gcc/src/type_of.rs @@ -73,7 +73,7 @@ pub fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLa // FIXME(eddyb) producing readable type names for trait objects can result // in problematically distinct types due to HRTB and subtyping (see #47638). // ty::Dynamic(..) | - ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str + ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) if !cx.sess().fewer_names() => { let mut name = with_no_trimmed_paths!(layout.ty.to_string()); diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs index 6c333afacc648..f0b549db9c0ad 100644 --- a/src/tools/clippy/clippy_lints/src/dereference.rs +++ b/src/tools/clippy/clippy_lints/src/dereference.rs @@ -1413,7 +1413,7 @@ fn ty_auto_deref_stability<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, precedenc | ty::Float(_) | ty::RawPtr(..) | ty::FnPtr(_) => Position::DerefStable(precedence, true).into(), - ty::Str | ty::Slice(..) => Position::DerefStable(precedence, false).into(), + ty::Slice(..) => Position::DerefStable(precedence, false).into(), ty::Adt(..) | ty::Foreign(_) | ty::FnDef(..) diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs index d0fab69496040..2be7ccf8af8c9 100644 --- a/src/tools/clippy/clippy_lints/src/format.rs +++ b/src/tools/clippy/clippy_lints/src/format.rs @@ -73,8 +73,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat { if format_args.format_string.parts == [kw::Empty]; if arg.format.is_default(); if match cx.typeck_results().expr_ty(value).peel_refs().kind() { - ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string(), - ty::Str => true, + ty::Adt(adt, _) => Some(adt.did()) == cx.tcx.lang_items().string() || adt.is_str(), _ => false, }; then { diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs index 29bdc46b647d5..606e635abe08e 100644 --- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs +++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs @@ -188,7 +188,7 @@ static KNOWN_WRAPPER_TYS: &[Symbol] = &[sym::Rc, sym::Arc]; fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet) -> bool { match *ty.kind() { // primitive types are never mutable - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => false, + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => false, ty::Adt(adt, substs) => { tys.insert(adt.did()) && !ty.is_freeze(cx.tcx, cx.param_env) || KNOWN_WRAPPER_TYS diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs index e13bc47973b10..d1658a622dbab 100644 --- a/src/tools/clippy/clippy_lints/src/len_zero.rs +++ b/src/tools/clippy/clippy_lints/src/len_zero.rs @@ -516,7 +516,7 @@ fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool { }), ty::Alias(ty::Projection, ref proj) => has_is_empty_impl(cx, proj.def_id), ty::Adt(id, _) => has_is_empty_impl(cx, id.did()), - ty::Array(..) | ty::Slice(..) | ty::Str => true, + ty::Array(..) | ty::Slice(..) => true, _ => false, } } diff --git a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs index 675a85ae5553a..f08891f7359d1 100644 --- a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs +++ b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs @@ -22,7 +22,7 @@ enum CaseMethod { pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, scrutinee: &'tcx Expr<'_>, arms: &'tcx [Arm<'_>]) { if_chain! { if let ty::Ref(_, ty, _) = cx.typeck_results().expr_ty(scrutinee).kind(); - if let ty::Str = ty.kind(); + if ty.is_str(); then { let mut visitor = MatchExprVisitor { cx, @@ -59,7 +59,7 @@ impl<'a, 'tcx> MatchExprVisitor<'a, 'tcx> { if let Some(case_method) = get_case_method(segment_ident) { let ty = self.cx.typeck_results().expr_ty(receiver).peel_refs(); - if is_type_lang_item(self.cx, ty, LangItem::String) || ty.kind() == &ty::Str { + if is_type_lang_item(self.cx, ty, LangItem::String) || ty.is_str() { self.case_method = Some(case_method); return true; } diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs index 56b7fbb9d4bc8..f6ba0979c441f 100644 --- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs +++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs @@ -6,7 +6,7 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; use rustc_lint::Lint; -use rustc_middle::ty::{self, DefIdTree}; +use rustc_middle::ty::DefIdTree; /// Wrapper fn for `CHARS_NEXT_CMP` and `CHARS_LAST_CMP` lints. pub(super) fn check( @@ -25,7 +25,7 @@ pub(super) fn check( let mut applicability = Applicability::MachineApplicable; let self_ty = cx.typeck_results().expr_ty_adjusted(args[0].0).peel_refs(); - if *self_ty.kind() != ty::Str { + if !self_ty.is_str() { return false; } diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs index 6ff7d5850e58f..a22285058d48e 100644 --- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs +++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs @@ -33,7 +33,7 @@ pub(super) fn check<'tcx>( if (method_name.ident.name == sym::as_str || method_name.ident.name == sym::as_ref) && { let arg_type = cx.typeck_results().expr_ty(receiver); let base_type = arg_type.peel_refs(); - *base_type.is_str() || is_type_lang_item(cx, base_type, hir::LangItem::String) + base_type.is_str() || is_type_lang_item(cx, base_type, hir::LangItem::String) } { receiver } else { @@ -54,7 +54,7 @@ pub(super) fn check<'tcx>( return false; } if let ty::Ref(_, ty, ..) = arg_ty.kind() { - if *ty.is_str() && can_be_static_str(cx, arg) { + if ty.is_str() && can_be_static_str(cx, arg) { return false; } }; diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs index 424482859ee87..4d7608c5670c7 100644 --- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs +++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs @@ -56,7 +56,7 @@ pub fn check( /// Returns whether `ty` specializes `ToString`. /// Currently, these are `str`, `String`, and `Cow<'_, str>`. fn specializes_tostring(cx: &LateContext<'_>, ty: Ty<'_>) -> bool { - if let ty::Str = ty.kind() { + if ty.is_str() { return true; } diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs index ef545380578ec..afdb8ce94ac43 100644 --- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs +++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs @@ -8,7 +8,6 @@ use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::PatKind; use rustc_lint::LateContext; -use rustc_middle::ty; use rustc_span::source_map::Span; use rustc_span::symbol::sym; diff --git a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs index 685ee93ffd857..2c20c6d752d70 100644 --- a/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs +++ b/src/tools/clippy/clippy_lints/src/methods/string_extend_chars.rs @@ -5,7 +5,6 @@ use clippy_utils::ty::is_type_lang_item; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_lint::LateContext; -use rustc_middle::ty; use super::STRING_EXTEND_CHARS; diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs index 4e5af1c7c7124..c3f4c83f9b762 100644 --- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs +++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs @@ -497,8 +497,8 @@ fn is_to_string_on_string_like<'a>( && let GenericArgKind::Type(ty) = generic_arg.unpack() && let Some(deref_trait_id) = cx.tcx.get_diagnostic_item(sym::Deref) && let Some(as_ref_trait_id) = cx.tcx.get_diagnostic_item(sym::AsRef) - && (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.types.str_) || - implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.types.str_.into()])) { + && (cx.get_associated_type(ty, deref_trait_id, "Target") == Some(cx.tcx.mk_str()) || + implements_trait(cx, ty, as_ref_trait_id, &[cx.tcx.mk_str().into()])) { true } else { false diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs index d88409c356e91..9a071431cab80 100644 --- a/src/tools/clippy/clippy_lints/src/ptr.rs +++ b/src/tools/clippy/clippy_lints/src/ptr.rs @@ -385,7 +385,7 @@ enum DerefTy<'tcx> { impl<'tcx> DerefTy<'tcx> { fn ty(&self, cx: &LateContext<'tcx>) -> Ty<'tcx> { match *self { - Self::Str => cx.tcx.types.str_, + Self::Str => cx.tcx.mk_str(), Self::Path => cx.tcx.mk_adt( cx.tcx.adt_def(cx.tcx.get_diagnostic_item(sym::Path).unwrap()), List::empty(), diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs index fabf2ad815034..9340639e34f9b 100644 --- a/src/tools/clippy/clippy_lints/src/strings.rs +++ b/src/tools/clippy/clippy_lints/src/strings.rs @@ -190,7 +190,7 @@ impl<'tcx> LateLintPass<'tcx> for StringAdd { }, ExprKind::Index(target, _idx) => { let e_ty = cx.typeck_results().expr_ty(target).peel_refs(); - if matches!(e_ty.kind(), ty::Str) || is_type_lang_item(cx, e_ty, LangItem::String) { + if is_type_lang_item(cx, e_ty, LangItem::Str) || is_type_lang_item(cx, e_ty, LangItem::String) { span_lint( cx, STRING_SLICE, diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs index afb7f2e132696..426c7253806e3 100644 --- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs +++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs @@ -22,7 +22,8 @@ pub(super) fn check<'tcx>( if let (ty::Ref(_, ty_from, from_mutbl), ty::Ref(_, ty_to, to_mutbl)) = (&from_ty.kind(), &to_ty.kind()) { if_chain! { - if let (&ty::Slice(slice_ty), &ty::Str) = (&ty_from.kind(), &ty_to.kind()); + if let ty::Slice(slice_ty) = *ty_from.kind(); + if ty_to.is_str(); if let ty::Uint(ty::UintTy::U8) = slice_ty.kind(); if from_mutbl == to_mutbl; then { diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs index a67bd8d46006b..89873275e0d1f 100644 --- a/src/tools/clippy/clippy_utils/src/consts.rs +++ b/src/tools/clippy/clippy_utils/src/consts.rs @@ -627,7 +627,7 @@ pub fn miri_to_const<'tcx>(tcx: TyCtxt<'tcx>, result: mir::ConstantKind<'tcx>) - }, mir::ConstantKind::Val(ConstValue::Slice { data, start, end }, _) => match result.ty().kind() { ty::Ref(_, tam, _) => match tam.kind() { - ty::Str => String::from_utf8( + ty::Adt(def, _) if def.is_str() => String::from_utf8( data.inner() .inspect_with_uninit_and_ptr_outside_interpreter(start..end) .to_owned(), diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs index 26b1d01974990..31ff368d1956d 100644 --- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs +++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs @@ -159,7 +159,7 @@ fn check_rvalue<'tcx>( return Err((span, "unsizing casts are only allowed for references right now".into())); }; let unsized_ty = tcx.struct_tail_erasing_lifetimes(pointee_ty, tcx.param_env(def_id)); - if let ty::Slice(_) | ty::Str = unsized_ty.kind() { + if let ty::Slice(_) = unsized_ty.kind() { check_operand(tcx, op, span, body)?; // Casting/coercing things to slices is fine. Ok(()) diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs index f293a7a3baeeb..a3bca61d78766 100644 --- a/src/tools/clippy/clippy_utils/src/ty.rs +++ b/src/tools/clippy/clippy_utils/src/ty.rs @@ -345,7 +345,9 @@ pub fn is_non_aggregate_primitive_type(ty: Ty<'_>) -> bool { /// floating-point number type, a `str`, or an array, slice, or tuple of those types). pub fn is_recursively_primitive_type(ty: Ty<'_>) -> bool { match *ty.kind() { - ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Str => true, + ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Float(_) => true, + // Keep considering str to be a primitive for suggestion purposes + ty::Adt(def, _) if def.is_str() => true, ty::Ref(_, inner, _) if inner.is_str() => true, ty::Array(inner_type, _) | ty::Slice(inner_type) => is_recursively_primitive_type(inner_type), ty::Tuple(inner_types) => inner_types.iter().all(is_recursively_primitive_type),