Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable] 1.72.1 release #115787

Merged
merged 8 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
10 changes: 10 additions & 0 deletions RELEASES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
Version 1.72.1 (2023-09-14)
===========================

- [Adjust codegen change to improve LLVM codegen](https://github.com/rust-lang/rust/pull/115236)
- [rustdoc: Fix self ty params in objects with lifetimes](https://github.com/rust-lang/rust/pull/115276)
- [Fix regression in compile times](https://github.com/rust-lang/rust/pull/114948)
- Resolve some ICE regressions in the compiler:
- [#115215](https://github.com/rust-lang/rust/pull/115215)
- [#115559](https://github.com/rust-lang/rust/pull/115559)

Version 1.72.0 (2023-08-24)
==========================

Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_codegen_llvm/src/type_of.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,11 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyAndLayout<'tcx> {

// Vectors, even for non-power-of-two sizes, have the same layout as
// arrays but don't count as aggregate types
// While LLVM theoretically supports non-power-of-two sizes, and they
// often work fine, sometimes x86-isel deals with them horribly
// (see #115212) so for now only use power-of-two ones.
if let FieldsShape::Array { count, .. } = self.layout.fields()
&& count.is_power_of_two()
&& let element = self.field(cx, 0)
&& element.ty.is_integral()
{
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_codegen_ssa/src/mir/locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use rustc_index::IndexVec;
use rustc_middle::mir;
use rustc_middle::ty::print::with_no_trimmed_paths;
use std::ops::{Index, IndexMut};

pub(super) struct Locals<'tcx, V> {
values: IndexVec<mir::Local, LocalRef<'tcx, V>>,
}
Expand Down Expand Up @@ -36,17 +35,18 @@ impl<'tcx, V> Locals<'tcx, V> {
impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub(super) fn initialize_locals(&mut self, values: Vec<LocalRef<'tcx, Bx::Value>>) {
assert!(self.locals.values.is_empty());

// FIXME(#115215): After #115025 get's merged this might not be necessary
for (local, value) in values.into_iter().enumerate() {
match value {
LocalRef::Place(_) | LocalRef::UnsizedPlace(_) | LocalRef::PendingOperand => (),
LocalRef::Operand(op) => {
let local = mir::Local::from_usize(local);
let expected_ty = self.monomorphize(self.mir.local_decls[local].ty);
assert_eq!(expected_ty, op.layout.ty, "unexpected initial operand type");
if expected_ty != op.layout.ty {
warn!("Unexpected initial operand type. See the issues/114858");
}
}
}

self.locals.values.push(value);
}
}
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_mir_transform/src/deduce_param_attrs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,12 @@ pub fn deduced_param_attrs<'tcx>(
body.local_decls.iter().skip(1).take(body.arg_count).enumerate().map(
|(arg_index, local_decl)| DeducedParamAttrs {
read_only: !deduce_read_only.mutable_args.contains(arg_index)
&& local_decl.ty.is_freeze(tcx, param_env),
// We must normalize here to reveal opaques and normalize
// their substs, otherwise we'll see exponential blow-up in
// compile times: #113372
&& tcx
.normalize_erasing_regions(param_env, local_decl.ty)
.is_freeze(tcx, param_env),
},
),
);
Expand Down
14 changes: 5 additions & 9 deletions compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,12 @@ impl<'a, 'tcx: 'a> InferCtxtExt<'a, 'tcx> for InferCtxt<'tcx> {
let ty = OpportunisticRegionResolver::new(self).fold_ty(ty);

// We do not expect existential variables in implied bounds.
// We may however encounter unconstrained lifetime variables in invalid
// code. See #110161 for context.
// We may however encounter unconstrained lifetime variables
// in very rare cases.
//
// See `ui/implied-bounds/implied-bounds-unconstrained-2.rs` for
// an example.
assert!(!ty.has_non_region_infer());
if ty.has_infer() {
self.tcx.sess.delay_span_bug(
self.tcx.def_span(body_id),
"skipped implied_outlives_bounds due to unconstrained lifetimes",
);
return vec![];
}

let mut canonical_var_values = OriginalQueryValues::default();
let canonical_ty =
Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/arm-android/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:22.10
FROM ubuntu:23.04

ARG DEBIAN_FRONTEND=noninteractive
COPY scripts/android-base-apt-get.sh /scripts/
Expand Down
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/dist-android/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:22.10
FROM ubuntu:23.04

COPY scripts/android-base-apt-get.sh /scripts/
RUN sh /scripts/android-base-apt-get.sh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@

set -ex

curl https://static.redox-os.org/toolchain/x86_64-unknown-redox/relibc-install.tar.gz | \
curl https://ci-mirrors.rust-lang.org/rustc/2022-11-27-relibc-install.tar.gz | \
tar --extract --gzip --directory /usr/local
2 changes: 1 addition & 1 deletion src/ci/docker/host-x86_64/x86_64-gnu-llvm-15/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM ubuntu:22.10
FROM ubuntu:23.04

ARG DEBIAN_FRONTEND=noninteractive

Expand Down
34 changes: 23 additions & 11 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,7 @@ fn clean_generic_bound<'tcx>(
let trait_ref = ty::Binder::dummy(ty::TraitRef::identity(cx.tcx, def_id));

let generic_args = clean_generic_args(generic_args, cx);
let GenericArgs::AngleBracketed { bindings, .. } = generic_args
else {
let GenericArgs::AngleBracketed { bindings, .. } = generic_args else {
bug!("clean: parenthesized `GenericBound::LangItemTrait`");
};

Expand Down Expand Up @@ -1818,33 +1817,46 @@ fn can_elide_trait_object_lifetime_bound<'tcx>(
#[derive(Debug)]
pub(crate) enum ContainerTy<'tcx> {
Ref(ty::Region<'tcx>),
Regular { ty: DefId, substs: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>, arg: usize },
Regular {
ty: DefId,
args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
has_self: bool,
arg: usize,
},
}

impl<'tcx> ContainerTy<'tcx> {
fn object_lifetime_default(self, tcx: TyCtxt<'tcx>) -> ObjectLifetimeDefault<'tcx> {
match self {
Self::Ref(region) => ObjectLifetimeDefault::Arg(region),
Self::Regular { ty: container, substs, arg: index } => {
Self::Regular { ty: container, args, has_self, arg: index } => {
let (DefKind::Struct
| DefKind::Union
| DefKind::Enum
| DefKind::TyAlias
| DefKind::Trait
| DefKind::AssocTy
| DefKind::Variant) = tcx.def_kind(container)
| DefKind::TyAlias { .. }
| DefKind::Trait) = tcx.def_kind(container)
else {
return ObjectLifetimeDefault::Empty;
};

let generics = tcx.generics_of(container);
let param = generics.params[index].def_id;
let default = tcx.object_lifetime_default(param);
debug_assert_eq!(generics.parent_count, 0);

// If the container is a trait object type, the arguments won't contain the self type but the
// generics of the corresponding trait will. In such a case, offset the index by one.
// For comparison, if the container is a trait inside a bound, the arguments do contain the
// self type.
let offset =
if !has_self && generics.parent.is_none() && generics.has_self { 1 } else { 0 };
let param = generics.params[index + offset].def_id;

let default = tcx.object_lifetime_default(param);
match default {
rbv::ObjectLifetimeDefault::Param(lifetime) => {
// The index is relative to the parent generics but since we don't have any,
// we don't need to translate it.
let index = generics.param_def_id_to_index[&lifetime];
let arg = substs.skip_binder()[index as usize].expect_region();
let arg = args.skip_binder()[index as usize].expect_region();
ObjectLifetimeDefault::Arg(arg)
}
rbv::ObjectLifetimeDefault::Empty => ObjectLifetimeDefault::Empty,
Expand Down
19 changes: 8 additions & 11 deletions src/librustdoc/clean/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
let primitives = local_crate.primitives(cx.tcx);
let keywords = local_crate.keywords(cx.tcx);
{
let ItemKind::ModuleItem(ref mut m) = *module.kind
else { unreachable!() };
let ItemKind::ModuleItem(ref mut m) = *module.kind else { unreachable!() };
m.items.extend(primitives.iter().map(|&(def_id, prim)| {
Item::from_def_id_and_parts(
def_id,
Expand All @@ -74,18 +73,15 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {

pub(crate) fn substs_to_args<'tcx>(
cx: &mut DocContext<'tcx>,
substs: ty::Binder<'tcx, &'tcx [ty::subst::GenericArg<'tcx>]>,
mut skip_first: bool,
args: ty::Binder<'tcx, &'tcx [ty::GenericArg<'tcx>]>,
has_self: bool,
container: Option<DefId>,
) -> Vec<GenericArg> {
let mut skip_first = has_self;
let mut ret_val =
Vec::with_capacity(substs.skip_binder().len().saturating_sub(if skip_first {
1
} else {
0
}));
Vec::with_capacity(args.skip_binder().len().saturating_sub(if skip_first { 1 } else { 0 }));

ret_val.extend(substs.iter().enumerate().filter_map(|(index, kind)| {
ret_val.extend(args.iter().enumerate().filter_map(|(index, kind)| {
match kind.skip_binder().unpack() {
GenericArgKind::Lifetime(lt) => {
Some(GenericArg::Lifetime(clean_middle_region(lt).unwrap_or(Lifetime::elided())))
Expand All @@ -100,7 +96,8 @@ pub(crate) fn substs_to_args<'tcx>(
None,
container.map(|container| crate::clean::ContainerTy::Regular {
ty: container,
substs,
args,
has_self,
arg: index,
}),
))),
Expand Down
2 changes: 1 addition & 1 deletion src/version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.72.0
1.72.1
21 changes: 15 additions & 6 deletions tests/codegen/mem-replace-simple-type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,21 @@ pub fn replace_ref_str<'a>(r: &mut &'a str, v: &'a str) -> &'a str {
}

#[no_mangle]
// CHECK-LABEL: @replace_short_array(
pub fn replace_short_array(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] {
// CHECK-LABEL: @replace_short_array_3(
pub fn replace_short_array_3(r: &mut [u32; 3], v: [u32; 3]) -> [u32; 3] {
// CHECK-NOT: alloca
// CHECK: %[[R:.+]] = load <3 x i32>, ptr %r, align 4
// CHECK: store <3 x i32> %[[R]], ptr %0
// CHECK: %[[V:.+]] = load <3 x i32>, ptr %v, align 4
// CHECK: store <3 x i32> %[[V]], ptr %r
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %0, ptr align 4 %r, i64 12, i1 false)
// CHECK: call void @llvm.memcpy.p0.p0.i64(ptr align 4 %r, ptr align 4 %v, i64 12, i1 false)
std::mem::replace(r, v)
}

#[no_mangle]
// CHECK-LABEL: @replace_short_array_4(
pub fn replace_short_array_4(r: &mut [u32; 4], v: [u32; 4]) -> [u32; 4] {
// CHECK-NOT: alloca
// CHECK: %[[R:.+]] = load <4 x i32>, ptr %r, align 4
// CHECK: store <4 x i32> %[[R]], ptr %0
// CHECK: %[[V:.+]] = load <4 x i32>, ptr %v, align 4
// CHECK: store <4 x i32> %[[V]], ptr %r
std::mem::replace(r, v)
}
33 changes: 24 additions & 9 deletions tests/codegen/swap-small-types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,12 @@ type RGB48 = [u16; 3];
// CHECK-LABEL: @swap_rgb48_manually(
#[no_mangle]
pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) {
// CHECK-NOT: alloca
// CHECK: %[[TEMP0:.+]] = load <3 x i16>, ptr %x, align 2
// CHECK: %[[TEMP1:.+]] = load <3 x i16>, ptr %y, align 2
// CHECK: store <3 x i16> %[[TEMP1]], ptr %x, align 2
// CHECK: store <3 x i16> %[[TEMP0]], ptr %y, align 2
// FIXME: See #115212 for why this has an alloca again

// CHECK: alloca [3 x i16], align 2
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)

let temp = *x;
*x = *y;
Expand All @@ -25,11 +26,25 @@ pub fn swap_rgb48_manually(x: &mut RGB48, y: &mut RGB48) {
// CHECK-LABEL: @swap_rgb48
#[no_mangle]
pub fn swap_rgb48(x: &mut RGB48, y: &mut RGB48) {
// FIXME: See #115212 for why this has an alloca again

// CHECK: alloca [3 x i16], align 2
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
// CHECK: call void @llvm.memcpy.p0.p0.i64({{.+}}, i64 6, i1 false)
swap(x, y)
}

type RGBA64 = [u16; 4];

// CHECK-LABEL: @swap_rgba64
#[no_mangle]
pub fn swap_rgba64(x: &mut RGBA64, y: &mut RGBA64) {
// CHECK-NOT: alloca
// CHECK: load <3 x i16>
// CHECK: load <3 x i16>
// CHECK: store <3 x i16>
// CHECK: store <3 x i16>
// CHECK-DAG: %[[XVAL:.+]] = load <4 x i16>, ptr %x, align 2
// CHECK-DAG: %[[YVAL:.+]] = load <4 x i16>, ptr %y, align 2
// CHECK-DAG: store <4 x i16> %[[YVAL]], ptr %x, align 2
// CHECK-DAG: store <4 x i16> %[[XVAL]], ptr %y, align 2
swap(x, y)
}

Expand Down
19 changes: 19 additions & 0 deletions tests/rustdoc/inline_cross/auxiliary/dyn_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,22 @@ pub trait HigherRankedBoundTrait1<'e> where for<'l> Self: 'e + 'l {}
pub trait AmbiguousBoundTrait<'a, 'b>: 'a + 'b {}

pub struct AmbiguousBoundWrapper<'a, 'b, T: ?Sized + 'a + 'b>(&'a T, &'b T);

// Trait objects inside of another trait object, a trait bound or an associated type.

pub trait Inner {}
pub trait Outer<T: ?Sized> {}
pub trait Base {
type Type<T: ?Sized>;
}
impl Base for () {
type Type<T: ?Sized> = ();
}

pub type NestedTraitObjects = dyn Outer<dyn Inner>;

pub fn apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner> {
o
}

pub type AssocTy = <() as Base>::Type<dyn Inner>;
15 changes: 15 additions & 0 deletions tests/rustdoc/inline_cross/dyn_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,3 +128,18 @@ pub use dyn_trait::BareAmbiguousBoundEarly1;
// @has user/type.BareAmbiguousBoundStatic.html
// @has - '//*[@class="rust item-decl"]//code' "dyn AmbiguousBoundTrait<'o, 'o> + 'static;"
pub use dyn_trait::BareAmbiguousBoundStatic;

// Regression test for issue #115179:

// @has user/type.NestedTraitObjects.html
// @has - '//*[@class="rust item-decl"]//code' "dyn Outer<dyn Inner>;"
pub use dyn_trait::NestedTraitObjects;

// @has user/fn.apit_rpit.html
// @has - '//pre[@class="rust item-decl"]' \
// "apit_rpit(o: impl Outer<dyn Inner>) -> impl Outer<dyn Inner>"
pub use dyn_trait::apit_rpit;

// @has user/type.AssocTy.html
// @has - '//*[@class="rust item-decl"]//code' "<() as Base>::Type<dyn Inner>"
pub use dyn_trait::AssocTy;
Loading
Loading