Skip to content

Commit 4f9dc0a

Browse files
committed
Auto merge of rust-lang#78783 - Mark-Simulacrum:beta-next, r=Mark-Simulacrum
[beta] backports This backports a number of PRs to beta: * Add delay_span_bug to no longer ICE rust-lang#78645 * Do not ICE on invalid input rust-lang#78422 * revert rust-lang#75443, update mir validator rust-lang#78410 * Do not try to report on closures to avoid ICE rust-lang#78268 * Disable "optimization to avoid load of address" in InstCombine rust-lang#78195 * Disable MatchBranchSimplification rust-lang#78151 * Do not ICE with TraitPredicates containing [type error] rust-lang#77930 * Tweak `if let` suggestion to be more liberal with suggestion and to not ICE rust-lang#77283 * Use different mirror for linux headers in musl-toolchain CI script. rust-lang#78316
2 parents 4c78178 + ec4ea4a commit 4f9dc0a

34 files changed

+492
-301
lines changed

compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs

+8
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
3939
) if **sub_r == RegionKind::ReStatic => {
4040
// This is for an implicit `'static` requirement coming from `impl dyn Trait {}`.
4141
if let ObligationCauseCode::UnifyReceiver(ctxt) = &cause.code {
42+
// This may have a closure and it would cause ICE
43+
// through `find_param_with_region` (#78262).
44+
let anon_reg_sup = tcx.is_suitable_region(sup_r)?;
45+
let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id);
46+
if fn_returns.is_empty() {
47+
return None;
48+
}
49+
4250
let param = self.find_param_with_region(sup_r, sub_r)?;
4351
let lifetime = if sup_r.has_name() {
4452
format!("lifetime `{}`", sup_r)

compiler/rustc_mir/src/transform/instcombine.rs

+5
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ impl OptimizationFinder<'b, 'tcx> {
119119
}
120120

121121
fn find_deref_of_address(&mut self, rvalue: &Rvalue<'tcx>, location: Location) -> Option<()> {
122+
// FIXME(#78192): This optimization can result in unsoundness.
123+
if !self.tcx.sess.opts.debugging_opts.unsound_mir_opts {
124+
return None;
125+
}
126+
122127
// Look for the sequence
123128
//
124129
// _2 = &_1;

compiler/rustc_mir/src/transform/match_branches.rs

+7
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ pub struct MatchBranchSimplification;
3838
3939
impl<'tcx> MirPass<'tcx> for MatchBranchSimplification {
4040
fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) {
41+
// FIXME: This optimization can result in unsoundness, because it introduces
42+
// additional uses of a place holding the discriminant value without ensuring that
43+
// it is valid to do so.
44+
if !tcx.sess.opts.debugging_opts.unsound_mir_opts {
45+
return;
46+
}
47+
4148
let param_env = tcx.param_env(src.def_id());
4249
let bbs = body.basic_blocks_mut();
4350
'outer: for bb_idx in bbs.indices() {

compiler/rustc_mir/src/transform/validate.rs

+21-75
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ use crate::dataflow::{Analysis, ResultsCursor};
55
use crate::util::storage::AlwaysLiveLocals;
66

77
use super::{MirPass, MirSource};
8+
use rustc_infer::infer::TyCtxtInferExt;
89
use rustc_middle::mir::visit::{PlaceContext, Visitor};
910
use rustc_middle::mir::{
1011
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, Rvalue,
1112
Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
1213
};
13-
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
14-
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
14+
use rustc_middle::ty::fold::BottomUpFolder;
15+
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable};
1516

1617
#[derive(Copy, Clone, Debug)]
1718
enum EdgeKind {
@@ -64,79 +65,24 @@ pub fn equal_up_to_regions(
6465
return true;
6566
}
6667

67-
struct LifetimeIgnoreRelation<'tcx> {
68-
tcx: TyCtxt<'tcx>,
69-
param_env: ty::ParamEnv<'tcx>,
70-
}
71-
72-
impl TypeRelation<'tcx> for LifetimeIgnoreRelation<'tcx> {
73-
fn tcx(&self) -> TyCtxt<'tcx> {
74-
self.tcx
75-
}
76-
77-
fn param_env(&self) -> ty::ParamEnv<'tcx> {
78-
self.param_env
79-
}
80-
81-
fn tag(&self) -> &'static str {
82-
"librustc_mir::transform::validate"
83-
}
84-
85-
fn a_is_expected(&self) -> bool {
86-
true
87-
}
88-
89-
fn relate_with_variance<T: Relate<'tcx>>(
90-
&mut self,
91-
_: ty::Variance,
92-
a: T,
93-
b: T,
94-
) -> RelateResult<'tcx, T> {
95-
// Ignore variance, require types to be exactly the same.
96-
self.relate(a, b)
97-
}
98-
99-
fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> {
100-
if a == b {
101-
// Short-circuit.
102-
return Ok(a);
103-
}
104-
ty::relate::super_relate_tys(self, a, b)
105-
}
106-
107-
fn regions(
108-
&mut self,
109-
a: ty::Region<'tcx>,
110-
_b: ty::Region<'tcx>,
111-
) -> RelateResult<'tcx, ty::Region<'tcx>> {
112-
// Ignore regions.
113-
Ok(a)
114-
}
115-
116-
fn consts(
117-
&mut self,
118-
a: &'tcx ty::Const<'tcx>,
119-
b: &'tcx ty::Const<'tcx>,
120-
) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> {
121-
ty::relate::super_relate_consts(self, a, b)
122-
}
123-
124-
fn binders<T>(
125-
&mut self,
126-
a: ty::Binder<T>,
127-
b: ty::Binder<T>,
128-
) -> RelateResult<'tcx, ty::Binder<T>>
129-
where
130-
T: Relate<'tcx>,
131-
{
132-
self.relate(a.skip_binder(), b.skip_binder())?;
133-
Ok(a)
134-
}
135-
}
136-
137-
// Instantiate and run relation.
138-
let mut relator: LifetimeIgnoreRelation<'tcx> = LifetimeIgnoreRelation { tcx: tcx, param_env };
139-
relator.relate(src, dest).is_ok()
68+
// Normalize lifetimes away on both sides, then compare.
69+
let param_env = param_env.with_reveal_all_normalized(tcx);
70+
let normalize = |ty: Ty<'tcx>| {
71+
tcx.normalize_erasing_regions(
72+
param_env,
73+
ty.fold_with(&mut BottomUpFolder {
74+
tcx,
75+
// We just erase all late-bound lifetimes, but this is not fully correct (FIXME):
76+
// lifetimes in invariant positions could matter (e.g. through associated types).
77+
// We rely on the fact that layout was confirmed to be equal above.
78+
lt_op: |_| tcx.lifetimes.re_erased,
79+
// Leave consts and types unchanged.
80+
ct_op: |ct| ct,
81+
ty_op: |ty| ty,
82+
}),
83+
)
84+
};
85+
tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok())
14086
}
14187

14288
struct TypeChecker<'a, 'tcx> {

compiler/rustc_trait_selection/src/traits/codegen/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,10 @@ where
118118
// contains unbound type parameters. It could be a slight
119119
// optimization to stop iterating early.
120120
if let Err(errors) = fulfill_cx.select_all_or_error(infcx) {
121-
bug!("Encountered errors `{:?}` resolving bounds after type-checking", errors);
121+
infcx.tcx.sess.delay_span_bug(
122+
rustc_span::DUMMY_SP,
123+
&format!("Encountered errors `{:?}` resolving bounds after type-checking", errors),
124+
);
122125
}
123126

124127
let result = infcx.resolve_vars_if_possible(result);

compiler/rustc_trait_selection/src/traits/object_safety.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -424,10 +424,17 @@ fn virtual_call_violation_for_method<'tcx>(
424424

425425
let param_env = tcx.param_env(method.def_id);
426426

427-
let abi_of_ty = |ty: Ty<'tcx>| -> &Abi {
427+
let abi_of_ty = |ty: Ty<'tcx>| -> Option<&Abi> {
428428
match tcx.layout_of(param_env.and(ty)) {
429-
Ok(layout) => &layout.abi,
430-
Err(err) => bug!("error: {}\n while computing layout for type {:?}", err, ty),
429+
Ok(layout) => Some(&layout.abi),
430+
Err(err) => {
431+
// #78372
432+
tcx.sess.delay_span_bug(
433+
tcx.def_span(method.def_id),
434+
&format!("error: {}\n while computing layout for type {:?}", err, ty),
435+
);
436+
None
437+
}
431438
}
432439
};
433440

@@ -436,7 +443,7 @@ fn virtual_call_violation_for_method<'tcx>(
436443
receiver_for_self_ty(tcx, receiver_ty, tcx.mk_unit(), method.def_id);
437444

438445
match abi_of_ty(unit_receiver_ty) {
439-
&Abi::Scalar(..) => (),
446+
Some(Abi::Scalar(..)) => (),
440447
abi => {
441448
tcx.sess.delay_span_bug(
442449
tcx.def_span(method.def_id),
@@ -456,13 +463,12 @@ fn virtual_call_violation_for_method<'tcx>(
456463
receiver_for_self_ty(tcx, receiver_ty, trait_object_ty, method.def_id);
457464

458465
match abi_of_ty(trait_object_receiver) {
459-
&Abi::ScalarPair(..) => (),
466+
Some(Abi::ScalarPair(..)) => (),
460467
abi => {
461468
tcx.sess.delay_span_bug(
462469
tcx.def_span(method.def_id),
463470
&format!(
464-
"receiver when `Self = {}` should have a ScalarPair ABI; \
465-
found {:?}",
471+
"receiver when `Self = {}` should have a ScalarPair ABI; found {:?}",
466472
trait_object_ty, abi
467473
),
468474
);

compiler/rustc_trait_selection/src/traits/project.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
346346

347347
let ty = ty.super_fold_with(self);
348348
match *ty.kind() {
349-
ty::Opaque(def_id, substs) => {
349+
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
350350
// Only normalize `impl Trait` after type-checking, usually in codegen.
351351
match self.param_env.reveal() {
352352
Reveal::UserFacing => ty,

compiler/rustc_trait_selection/src/traits/query/normalize.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
108108

109109
let ty = ty.super_fold_with(self);
110110
let res = (|| match *ty.kind() {
111-
ty::Opaque(def_id, substs) => {
111+
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
112112
// Only normalize `impl Trait` after type-checking, usually in codegen.
113113
match self.param_env.reveal() {
114114
Reveal::UserFacing => ty,

compiler/rustc_typeck/src/check/expr.rs

+28-22
Original file line numberDiff line numberDiff line change
@@ -768,34 +768,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
768768
let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
769769
let lhs_ty = self.check_expr(&lhs);
770770
let rhs_ty = self.check_expr(&rhs);
771-
if self.can_coerce(lhs_ty, rhs_ty) {
772-
if !lhs.is_syntactic_place_expr() {
773-
// Do not suggest `if let x = y` as `==` is way more likely to be the intention.
774-
if let hir::Node::Expr(hir::Expr {
775-
kind: ExprKind::Match(_, _, hir::MatchSource::IfDesugar { .. }),
776-
..
777-
}) = self.tcx.hir().get(
778-
self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
779-
) {
780-
// Likely `if let` intended.
781-
err.span_suggestion_verbose(
782-
expr.span.shrink_to_lo(),
783-
"you might have meant to use pattern matching",
784-
"let ".to_string(),
785-
Applicability::MaybeIncorrect,
786-
);
787-
}
771+
let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
772+
(Applicability::MachineApplicable, true)
773+
} else {
774+
(Applicability::MaybeIncorrect, false)
775+
};
776+
if !lhs.is_syntactic_place_expr() {
777+
// Do not suggest `if let x = y` as `==` is way more likely to be the intention.
778+
if let hir::Node::Expr(hir::Expr {
779+
kind:
780+
ExprKind::Match(
781+
_,
782+
_,
783+
hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar,
784+
),
785+
..
786+
}) = self.tcx.hir().get(
787+
self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
788+
) {
789+
// Likely `if let` intended.
790+
err.span_suggestion_verbose(
791+
expr.span.shrink_to_lo(),
792+
"you might have meant to use pattern matching",
793+
"let ".to_string(),
794+
applicability,
795+
);
788796
}
797+
}
798+
if eq {
789799
err.span_suggestion_verbose(
790800
*span,
791801
"you might have meant to compare for equality",
792802
"==".to_string(),
793-
Applicability::MaybeIncorrect,
803+
applicability,
794804
);
795-
} else {
796-
// Do this to cause extra errors about the assignment.
797-
let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
798-
let _ = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
799805
}
800806

801807
if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() {

compiler/rustc_typeck/src/collect/type_of.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,13 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
7979
let _tables = tcx.typeck(body_owner);
8080
&*path
8181
}
82-
_ => span_bug!(DUMMY_SP, "unexpected const parent path {:?}", parent_node),
82+
_ => {
83+
tcx.sess.delay_span_bug(
84+
tcx.def_span(def_id),
85+
&format!("unexpected const parent path {:?}", parent_node),
86+
);
87+
return None;
88+
}
8389
};
8490

8591
// We've encountered an `AnonConst` in some path, so we need to

src/ci/docker/host-x86_64/armhf-gnu/Dockerfile

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ RUN curl https://www.busybox.net/downloads/busybox-1.21.1.tar.bz2 | tar xjf - &&
5858
# Download the ubuntu rootfs, which we'll use as a chroot for all our tests.
5959
WORKDIR /tmp
6060
RUN mkdir rootfs/ubuntu
61-
RUN curl http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04-core-armhf.tar.gz | \
61+
RUN curl http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.6-base-armhf.tar.gz | \
6262
tar xzf - -C rootfs/ubuntu && \
6363
cd rootfs && mkdir proc sys dev etc etc/init.d
6464

src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
// + span: $DIR/ref_deref.rs:5:6: 5:10
2020
// + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
2121
_2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10
22-
- _1 = (*_4); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
22+
- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
2323
+ _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10
2424
StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11
2525
StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11

src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
// + span: $DIR/ref_deref_project.rs:5:6: 5:17
2020
// + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) }
2121
_2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17
22-
_1 = ((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
22+
_1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17
2323
StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
2424
StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18
2525
_0 = const (); // scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2

src/test/mir-opt/inst_combine_deref.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-flags: -O
1+
// compile-flags: -O -Zunsound-mir-opts
22
// EMIT_MIR inst_combine_deref.simple_opt.InstCombine.diff
33
fn simple_opt() -> u64 {
44
let x = 5;

0 commit comments

Comments
 (0)