Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.",
Expand Down Expand Up @@ -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, _) => {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/debuginfo/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/traits/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/const_eval/eval_queries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/src/const_eval/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {:?}",
Expand Down
36 changes: 20 additions & 16 deletions compiler/rustc_const_eval/src/const_eval/valtrees.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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();

Expand All @@ -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);
Expand Down Expand Up @@ -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()),
}
Expand Down Expand Up @@ -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);

Expand All @@ -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
Expand Down Expand Up @@ -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 =>
{
Expand Down
16 changes: 15 additions & 1 deletion compiler/rustc_const_eval/src/interpret/eval_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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);

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/src/interpret/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(_)
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_const_eval/src/interpret/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/src/interpret/projection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
),
}
}
Expand Down
12 changes: 1 addition & 11 deletions compiler/rustc_const_eval/src/interpret/validity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -813,15 +812,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
fields: impl Iterator<Item = InterpResult<'tcx, Self::V>>,
) -> 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.
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_const_eval/src/util/type_name.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(_)
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_hir/src/lang_items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,6 @@ impl<'tcx> InherentCollect<'tcx> {
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Str
| ty::Array(..)
| ty::Slice(_)
| ty::RawPtr(_)
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/coherence/orphan.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,6 @@ fn do_orphan_check_impl<'tcx>(
| ty::Int(..)
| ty::Uint(..)
| ty::Float(..)
| ty::Str
| ty::Array(..)
| ty::Slice(..)
| ty::RawPtr(..)
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_analysis/src/variance/constraints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_hir_typeck/src/demand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -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()
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_hir_typeck/src/expectation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) => {
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/method/probe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
| ty::Int(_)
| ty::Uint(_)
| ty::Float(_)
| ty::Str
| ty::Array(..)
| ty::Slice(_)
| ty::RawPtr(_)
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_hir_typeck/src/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading