From 55856d7b4495aef31cb66a6a377818730cb1be39 Mon Sep 17 00:00:00 2001 From: kadmin Date: Sun, 1 Nov 2020 22:31:19 +0000 Subject: [PATCH 01/11] Add delay_span_bug to no longer ICE --- compiler/rustc_typeck/src/collect/type_of.rs | 8 +++++++- src/test/ui/issues/issue-78622.rs | 7 +++++++ src/test/ui/issues/issue-78622.stderr | 9 +++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/issues/issue-78622.rs create mode 100644 src/test/ui/issues/issue-78622.stderr diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 4b3250a1d443a..f6dca4a99c91d 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -79,7 +79,13 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option< let _tables = tcx.typeck(body_owner); &*path } - _ => span_bug!(DUMMY_SP, "unexpected const parent path {:?}", parent_node), + _ => { + tcx.sess.delay_span_bug( + tcx.def_span(def_id), + &format!("unexpected const parent path {:?}", parent_node), + ); + return None; + } }; // We've encountered an `AnonConst` in some path, so we need to diff --git a/src/test/ui/issues/issue-78622.rs b/src/test/ui/issues/issue-78622.rs new file mode 100644 index 0000000000000..c00fd26606367 --- /dev/null +++ b/src/test/ui/issues/issue-78622.rs @@ -0,0 +1,7 @@ +#![crate_type = "lib"] + +struct S; +fn f() { + S::A:: {} + //~^ ERROR ambiguous associated type +} diff --git a/src/test/ui/issues/issue-78622.stderr b/src/test/ui/issues/issue-78622.stderr new file mode 100644 index 0000000000000..f13073da0a36e --- /dev/null +++ b/src/test/ui/issues/issue-78622.stderr @@ -0,0 +1,9 @@ +error[E0223]: ambiguous associated type + --> $DIR/issue-78622.rs:5:5 + | +LL | S::A:: {} + | ^^^^^^^^^ help: use fully-qualified syntax: `::A` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0223`. From b10ee97e658971af56ba3718a63ccc2d5d5ea8c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Mon, 26 Oct 2020 16:56:22 -0700 Subject: [PATCH 02/11] Do not ICE on invalid input --- .../src/traits/object_safety.rs | 20 +++--- src/test/ui/issues/issue-78372.rs | 14 +++++ src/test/ui/issues/issue-78372.stderr | 62 +++++++++++++++++++ 3 files changed, 89 insertions(+), 7 deletions(-) create mode 100644 src/test/ui/issues/issue-78372.rs create mode 100644 src/test/ui/issues/issue-78372.stderr diff --git a/compiler/rustc_trait_selection/src/traits/object_safety.rs b/compiler/rustc_trait_selection/src/traits/object_safety.rs index 2f2ac9f094dc2..86fc3cbfea501 100644 --- a/compiler/rustc_trait_selection/src/traits/object_safety.rs +++ b/compiler/rustc_trait_selection/src/traits/object_safety.rs @@ -424,10 +424,17 @@ fn virtual_call_violation_for_method<'tcx>( let param_env = tcx.param_env(method.def_id); - let abi_of_ty = |ty: Ty<'tcx>| -> &Abi { + let abi_of_ty = |ty: Ty<'tcx>| -> Option<&Abi> { match tcx.layout_of(param_env.and(ty)) { - Ok(layout) => &layout.abi, - Err(err) => bug!("error: {}\n while computing layout for type {:?}", err, ty), + Ok(layout) => Some(&layout.abi), + Err(err) => { + // #78372 + tcx.sess.delay_span_bug( + tcx.def_span(method.def_id), + &format!("error: {}\n while computing layout for type {:?}", err, ty), + ); + None + } } }; @@ -436,7 +443,7 @@ fn virtual_call_violation_for_method<'tcx>( receiver_for_self_ty(tcx, receiver_ty, tcx.mk_unit(), method.def_id); match abi_of_ty(unit_receiver_ty) { - &Abi::Scalar(..) => (), + Some(Abi::Scalar(..)) => (), abi => { tcx.sess.delay_span_bug( tcx.def_span(method.def_id), @@ -456,13 +463,12 @@ fn virtual_call_violation_for_method<'tcx>( receiver_for_self_ty(tcx, receiver_ty, trait_object_ty, method.def_id); match abi_of_ty(trait_object_receiver) { - &Abi::ScalarPair(..) => (), + Some(Abi::ScalarPair(..)) => (), abi => { tcx.sess.delay_span_bug( tcx.def_span(method.def_id), &format!( - "receiver when `Self = {}` should have a ScalarPair ABI; \ - found {:?}", + "receiver when `Self = {}` should have a ScalarPair ABI; found {:?}", trait_object_ty, abi ), ); diff --git a/src/test/ui/issues/issue-78372.rs b/src/test/ui/issues/issue-78372.rs new file mode 100644 index 0000000000000..77a8c92c81c7e --- /dev/null +++ b/src/test/ui/issues/issue-78372.rs @@ -0,0 +1,14 @@ +use std::ops::DispatchFromDyn; //~ ERROR use of unstable library feature 'dispatch_from_dyn' +struct Smaht(PhantomData); //~ ERROR cannot find type `PhantomData` in this scope +impl DispatchFromDyn> for T {} //~ ERROR cannot find type `U` in this scope +//~^ ERROR cannot find type `MISC` in this scope +//~| ERROR use of unstable library feature 'dispatch_from_dyn' +//~| ERROR the trait `DispatchFromDyn` may only be implemented for a coercion between structures +//~| ERROR type parameter `T` must be covered by another type when it appears before the first +trait Foo: X {} +trait X { + fn foo(self: Smaht); +} +trait Marker {} +impl Marker for dyn Foo {} +fn main() {} diff --git a/src/test/ui/issues/issue-78372.stderr b/src/test/ui/issues/issue-78372.stderr new file mode 100644 index 0000000000000..9cdec1a5df6de --- /dev/null +++ b/src/test/ui/issues/issue-78372.stderr @@ -0,0 +1,62 @@ +error[E0412]: cannot find type `PhantomData` in this scope + --> $DIR/issue-78372.rs:2:23 + | +LL | struct Smaht(PhantomData); + | ^^^^^^^^^^^ not found in this scope + | +help: consider importing this struct + | +LL | use std::marker::PhantomData; + | + +error[E0412]: cannot find type `U` in this scope + --> $DIR/issue-78372.rs:3:31 + | +LL | impl DispatchFromDyn> for T {} + | - ^ help: a type parameter with a similar name exists: `T` + | | + | similarly named type parameter `T` defined here + +error[E0412]: cannot find type `MISC` in this scope + --> $DIR/issue-78372.rs:3:34 + | +LL | impl DispatchFromDyn> for T {} + | - ^^^^ not found in this scope + | | + | help: you might be missing a type parameter: `, MISC` + +error[E0658]: use of unstable library feature 'dispatch_from_dyn' + --> $DIR/issue-78372.rs:1:5 + | +LL | use std::ops::DispatchFromDyn; + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable + +error[E0658]: use of unstable library feature 'dispatch_from_dyn' + --> $DIR/issue-78372.rs:3:9 + | +LL | impl DispatchFromDyn> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: add `#![feature(dispatch_from_dyn)]` to the crate attributes to enable + +error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures + --> $DIR/issue-78372.rs:3:1 + | +LL | impl DispatchFromDyn> for T {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`) + --> $DIR/issue-78372.rs:3:6 + | +LL | impl DispatchFromDyn> for T {} + | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Smaht<[type error], [type error]>`) + | + = note: implementing a foreign trait is only possible if at least one of the types for which is it implemented is local, and no uncovered type parameters appear before that first local type + = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait for T0`, where `T0` is the first and `Tn` is the last + +error: aborting due to 7 previous errors + +Some errors have detailed explanations: E0210, E0378, E0412, E0658. +For more information about an error, try `rustc --explain E0210`. From 98286f92cf063f72ebf8dafebec0ec63da88eed3 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Mon, 26 Oct 2020 20:32:34 +0100 Subject: [PATCH 03/11] revert #75443 update mir validator --- compiler/rustc_mir/src/transform/validate.rs | 96 ++++--------------- .../src/traits/project.rs | 2 +- .../src/traits/query/normalize.rs | 2 +- .../ui/type-alias-impl-trait/issue-72793.rs | 27 ------ 4 files changed, 23 insertions(+), 104 deletions(-) delete mode 100644 src/test/ui/type-alias-impl-trait/issue-72793.rs diff --git a/compiler/rustc_mir/src/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs index ba7554cf02bde..94018a39b194f 100644 --- a/compiler/rustc_mir/src/transform/validate.rs +++ b/compiler/rustc_mir/src/transform/validate.rs @@ -5,13 +5,14 @@ use crate::dataflow::{Analysis, ResultsCursor}; use crate::util::storage::AlwaysLiveLocals; use super::{MirPass, MirSource}; +use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::visit::{PlaceContext, Visitor}; use rustc_middle::mir::{ AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo, }; -use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation}; -use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt}; +use rustc_middle::ty::fold::BottomUpFolder; +use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable}; #[derive(Copy, Clone, Debug)] enum EdgeKind { @@ -64,79 +65,24 @@ pub fn equal_up_to_regions( return true; } - struct LifetimeIgnoreRelation<'tcx> { - tcx: TyCtxt<'tcx>, - param_env: ty::ParamEnv<'tcx>, - } - - impl TypeRelation<'tcx> for LifetimeIgnoreRelation<'tcx> { - fn tcx(&self) -> TyCtxt<'tcx> { - self.tcx - } - - fn param_env(&self) -> ty::ParamEnv<'tcx> { - self.param_env - } - - fn tag(&self) -> &'static str { - "librustc_mir::transform::validate" - } - - fn a_is_expected(&self) -> bool { - true - } - - fn relate_with_variance>( - &mut self, - _: ty::Variance, - a: T, - b: T, - ) -> RelateResult<'tcx, T> { - // Ignore variance, require types to be exactly the same. - self.relate(a, b) - } - - fn tys(&mut self, a: Ty<'tcx>, b: Ty<'tcx>) -> RelateResult<'tcx, Ty<'tcx>> { - if a == b { - // Short-circuit. - return Ok(a); - } - ty::relate::super_relate_tys(self, a, b) - } - - fn regions( - &mut self, - a: ty::Region<'tcx>, - _b: ty::Region<'tcx>, - ) -> RelateResult<'tcx, ty::Region<'tcx>> { - // Ignore regions. - Ok(a) - } - - fn consts( - &mut self, - a: &'tcx ty::Const<'tcx>, - b: &'tcx ty::Const<'tcx>, - ) -> RelateResult<'tcx, &'tcx ty::Const<'tcx>> { - ty::relate::super_relate_consts(self, a, b) - } - - fn binders( - &mut self, - a: ty::Binder, - b: ty::Binder, - ) -> RelateResult<'tcx, ty::Binder> - where - T: Relate<'tcx>, - { - self.relate(a.skip_binder(), b.skip_binder())?; - Ok(a) - } - } - - // Instantiate and run relation. - let mut relator: LifetimeIgnoreRelation<'tcx> = LifetimeIgnoreRelation { tcx: tcx, param_env }; - relator.relate(src, dest).is_ok() + // Normalize lifetimes away on both sides, then compare. + let param_env = param_env.with_reveal_all_normalized(tcx); + let normalize = |ty: Ty<'tcx>| { + tcx.normalize_erasing_regions( + param_env, + ty.fold_with(&mut BottomUpFolder { + tcx, + // We just erase all late-bound lifetimes, but this is not fully correct (FIXME): + // lifetimes in invariant positions could matter (e.g. through associated types). + // We rely on the fact that layout was confirmed to be equal above. + lt_op: |_| tcx.lifetimes.re_erased, + // Leave consts and types unchanged. + ct_op: |ct| ct, + ty_op: |ty| ty, + }), + ) + }; + tcx.infer_ctxt().enter(|infcx| infcx.can_eq(param_env, normalize(src), normalize(dest)).is_ok()) } struct TypeChecker<'a, 'tcx> { diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs index ef8f7b69b5d60..6ac620b01b30e 100644 --- a/compiler/rustc_trait_selection/src/traits/project.rs +++ b/compiler/rustc_trait_selection/src/traits/project.rs @@ -346,7 +346,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { let ty = ty.super_fold_with(self); match *ty.kind() { - ty::Opaque(def_id, substs) => { + ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty, diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs index 3dcebbcc24482..c0ae7bf6973a6 100644 --- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs +++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs @@ -108,7 +108,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { let ty = ty.super_fold_with(self); let res = (|| match *ty.kind() { - ty::Opaque(def_id, substs) => { + ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => { // Only normalize `impl Trait` after type-checking, usually in codegen. match self.param_env.reveal() { Reveal::UserFacing => ty, diff --git a/src/test/ui/type-alias-impl-trait/issue-72793.rs b/src/test/ui/type-alias-impl-trait/issue-72793.rs deleted file mode 100644 index e643a8cab5b02..0000000000000 --- a/src/test/ui/type-alias-impl-trait/issue-72793.rs +++ /dev/null @@ -1,27 +0,0 @@ -// build-pass - -// Regression test for #72793. -// FIXME: This still shows ICE with `-Zmir-opt-level=2`. - -#![feature(type_alias_impl_trait)] - -trait T { type Item; } - -type Alias<'a> = impl T; - -struct S; -impl<'a> T for &'a S { - type Item = &'a (); -} - -fn filter_positive<'a>() -> Alias<'a> { - &S -} - -fn with_positive(fun: impl Fn(Alias<'_>)) { - fun(filter_positive()); -} - -fn main() { - with_positive(|_| ()); -} From 88d64f5e89eac73bb3c4eb7cfc3dd6a01a241035 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Fri, 23 Oct 2020 18:00:18 +0900 Subject: [PATCH 04/11] Do not try to report on closures to avoid ICE --- .../nice_region_error/static_impl_trait.rs | 8 ++++++++ src/test/ui/regions/issue-78262.rs | 9 +++++++++ src/test/ui/regions/issue-78262.stderr | 18 ++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 src/test/ui/regions/issue-78262.rs create mode 100644 src/test/ui/regions/issue-78262.stderr diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs index 441cfeea20a48..e9d5ebad7de03 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/static_impl_trait.rs @@ -39,6 +39,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { ) if **sub_r == RegionKind::ReStatic => { // This is for an implicit `'static` requirement coming from `impl dyn Trait {}`. if let ObligationCauseCode::UnifyReceiver(ctxt) = &cause.code { + // This may have a closure and it would cause ICE + // through `find_param_with_region` (#78262). + let anon_reg_sup = tcx.is_suitable_region(sup_r)?; + let fn_returns = tcx.return_type_impl_or_dyn_traits(anon_reg_sup.def_id); + if fn_returns.is_empty() { + return None; + } + let param = self.find_param_with_region(sup_r, sub_r)?; let lifetime = if sup_r.has_name() { format!("lifetime `{}`", sup_r) diff --git a/src/test/ui/regions/issue-78262.rs b/src/test/ui/regions/issue-78262.rs new file mode 100644 index 0000000000000..2324152d2c081 --- /dev/null +++ b/src/test/ui/regions/issue-78262.rs @@ -0,0 +1,9 @@ +trait TT {} + +impl dyn TT { + fn func(&self) {} +} + +fn main() { + let f = |x: &dyn TT| x.func(); //~ ERROR: mismatched types +} diff --git a/src/test/ui/regions/issue-78262.stderr b/src/test/ui/regions/issue-78262.stderr new file mode 100644 index 0000000000000..580cea00ecd4f --- /dev/null +++ b/src/test/ui/regions/issue-78262.stderr @@ -0,0 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/issue-78262.rs:8:28 + | +LL | let f = |x: &dyn TT| x.func(); + | ^^^^ lifetime mismatch + | + = note: expected reference `&(dyn TT + 'static)` + found reference `&dyn TT` +note: the anonymous lifetime #1 defined on the body at 8:13... + --> $DIR/issue-78262.rs:8:13 + | +LL | let f = |x: &dyn TT| x.func(); + | ^^^^^^^^^^^^^^^^^^^^^ + = note: ...does not necessarily outlive the static lifetime + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From 450eb69b942743e53dcfb2e4f180fad132c6314f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 25 Oct 2020 11:43:26 +0900 Subject: [PATCH 05/11] Test with NLL explicitly --- .../{issue-78262.stderr => issue-78262.default.stderr} | 6 +++--- src/test/ui/regions/issue-78262.nll.stderr | 10 ++++++++++ src/test/ui/regions/issue-78262.rs | 7 ++++++- 3 files changed, 19 insertions(+), 4 deletions(-) rename src/test/ui/regions/{issue-78262.stderr => issue-78262.default.stderr} (79%) create mode 100644 src/test/ui/regions/issue-78262.nll.stderr diff --git a/src/test/ui/regions/issue-78262.stderr b/src/test/ui/regions/issue-78262.default.stderr similarity index 79% rename from src/test/ui/regions/issue-78262.stderr rename to src/test/ui/regions/issue-78262.default.stderr index 580cea00ecd4f..e97b8eca94892 100644 --- a/src/test/ui/regions/issue-78262.stderr +++ b/src/test/ui/regions/issue-78262.default.stderr @@ -1,13 +1,13 @@ error[E0308]: mismatched types - --> $DIR/issue-78262.rs:8:28 + --> $DIR/issue-78262.rs:12:28 | LL | let f = |x: &dyn TT| x.func(); | ^^^^ lifetime mismatch | = note: expected reference `&(dyn TT + 'static)` found reference `&dyn TT` -note: the anonymous lifetime #1 defined on the body at 8:13... - --> $DIR/issue-78262.rs:8:13 +note: the anonymous lifetime #1 defined on the body at 12:13... + --> $DIR/issue-78262.rs:12:13 | LL | let f = |x: &dyn TT| x.func(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/regions/issue-78262.nll.stderr b/src/test/ui/regions/issue-78262.nll.stderr new file mode 100644 index 0000000000000..4607dbad4220b --- /dev/null +++ b/src/test/ui/regions/issue-78262.nll.stderr @@ -0,0 +1,10 @@ +error[E0521]: borrowed data escapes outside of closure + --> $DIR/issue-78262.rs:12:26 + | +LL | let f = |x: &dyn TT| x.func(); + | - ^^^^^^^^ `x` escapes the closure body here + | | + | `x` is a reference that is only valid in the closure body + +error: aborting due to previous error + diff --git a/src/test/ui/regions/issue-78262.rs b/src/test/ui/regions/issue-78262.rs index 2324152d2c081..0bdb0abac307d 100644 --- a/src/test/ui/regions/issue-78262.rs +++ b/src/test/ui/regions/issue-78262.rs @@ -1,3 +1,7 @@ +// revisions: nll default +// ignore-compare-mode-nll +//[nll]compile-flags: -Z borrowck=mir + trait TT {} impl dyn TT { @@ -5,5 +9,6 @@ impl dyn TT { } fn main() { - let f = |x: &dyn TT| x.func(); //~ ERROR: mismatched types + let f = |x: &dyn TT| x.func(); //[default]~ ERROR: mismatched types + //[nll]~^ ERROR: borrowed data escapes outside of closure } From 83dd70633e9665b60c0b561a19ae2daea8815035 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Wed, 21 Oct 2020 00:00:00 +0000 Subject: [PATCH 06/11] Disable "optimization to avoid load of address" in InstCombine --- compiler/rustc_mir/src/transform/instcombine.rs | 5 +++++ src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff | 2 +- .../mir-opt/const_prop/ref_deref_project.main.ConstProp.diff | 2 +- src/test/mir-opt/inst_combine_deref.rs | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_mir/src/transform/instcombine.rs b/compiler/rustc_mir/src/transform/instcombine.rs index 3ed0aea1404d4..ada24899e135d 100644 --- a/compiler/rustc_mir/src/transform/instcombine.rs +++ b/compiler/rustc_mir/src/transform/instcombine.rs @@ -119,6 +119,11 @@ impl OptimizationFinder<'b, 'tcx> { } fn find_deref_of_address(&mut self, rvalue: &Rvalue<'tcx>, location: Location) -> Option<()> { + // FIXME(#78192): This optimization can result in unsoundness. + if !self.tcx.sess.opts.debugging_opts.unsound_mir_opts { + return None; + } + // Look for the sequence // // _2 = &_1; diff --git a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff index feef65f52ebe0..4fd1b8b227649 100644 --- a/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref.main.ConstProp.diff @@ -19,7 +19,7 @@ // + span: $DIR/ref_deref.rs:5:6: 5:10 // + literal: Const { ty: &i32, val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref[317d]::main), const_param_did: None }, [], Some(promoted[0])) } _2 = _4; // scope 0 at $DIR/ref_deref.rs:5:6: 5:10 -- _1 = (*_4); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 +- _1 = (*_2); // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 + _1 = const 4_i32; // scope 0 at $DIR/ref_deref.rs:5:5: 5:10 StorageDead(_2); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11 StorageDead(_1); // scope 0 at $DIR/ref_deref.rs:5:10: 5:11 diff --git a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff index 7ec0751263fb1..812c7c9771801 100644 --- a/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff +++ b/src/test/mir-opt/const_prop/ref_deref_project.main.ConstProp.diff @@ -19,7 +19,7 @@ // + span: $DIR/ref_deref_project.rs:5:6: 5:17 // + literal: Const { ty: &(i32, i32), val: Unevaluated(WithOptConstParam { did: DefId(0:3 ~ ref_deref_project[317d]::main), const_param_did: None }, [], Some(promoted[0])) } _2 = &((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:6: 5:17 - _1 = ((*_4).1: i32); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 + _1 = (*_2); // scope 0 at $DIR/ref_deref_project.rs:5:5: 5:17 StorageDead(_2); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 StorageDead(_1); // scope 0 at $DIR/ref_deref_project.rs:5:17: 5:18 _0 = const (); // scope 0 at $DIR/ref_deref_project.rs:4:11: 6:2 diff --git a/src/test/mir-opt/inst_combine_deref.rs b/src/test/mir-opt/inst_combine_deref.rs index 3be8c2f3ac732..78361c336607c 100644 --- a/src/test/mir-opt/inst_combine_deref.rs +++ b/src/test/mir-opt/inst_combine_deref.rs @@ -1,4 +1,4 @@ -// compile-flags: -O +// compile-flags: -O -Zunsound-mir-opts // EMIT_MIR inst_combine_deref.simple_opt.InstCombine.diff fn simple_opt() -> u64 { let x = 5; From 49c5862cf6e594f38ee78ceadc5c61ff5b2c5e62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Tue, 20 Oct 2020 00:00:00 +0000 Subject: [PATCH 07/11] Disable MatchBranchSimplification This optimization can result in unsoundness, because it introduces additional uses of a place holding the discriminant value without ensuring that it is valid to do so. --- .../rustc_mir/src/transform/match_branches.rs | 7 ++ ...s.bar.MatchBranchSimplification.32bit.diff | 116 +++++++++--------- ...s.bar.MatchBranchSimplification.64bit.diff | 116 +++++++++--------- ...s.foo.MatchBranchSimplification.32bit.diff | 22 ++-- ...s.foo.MatchBranchSimplification.64bit.diff | 22 ++-- src/test/mir-opt/matches_reduce_branches.rs | 1 + .../not_equal_false.opt.InstCombine.diff | 45 +++++-- 7 files changed, 179 insertions(+), 150 deletions(-) diff --git a/compiler/rustc_mir/src/transform/match_branches.rs b/compiler/rustc_mir/src/transform/match_branches.rs index c1d574d6ef290..70ae5474a4f90 100644 --- a/compiler/rustc_mir/src/transform/match_branches.rs +++ b/compiler/rustc_mir/src/transform/match_branches.rs @@ -38,6 +38,13 @@ pub struct MatchBranchSimplification; impl<'tcx> MirPass<'tcx> for MatchBranchSimplification { fn run_pass(&self, tcx: TyCtxt<'tcx>, src: MirSource<'tcx>, body: &mut Body<'tcx>) { + // FIXME: This optimization can result in unsoundness, because it introduces + // additional uses of a place holding the discriminant value without ensuring that + // it is valid to do so. + if !tcx.sess.opts.debugging_opts.unsound_mir_opts { + return; + } + let param_env = tcx.param_env(src.def_id()); let bbs = body.basic_blocks_mut(); 'outer: for bb_idx in bbs.indices() { diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff index 3f01719e01bfc..648cf241cbaba 100644 --- a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.32bit.diff @@ -2,83 +2,83 @@ + // MIR for `bar` after MatchBranchSimplification fn bar(_1: i32) -> (bool, bool, bool, bool) { - debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:11:8: 11:9 - let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:11:19: 11:43 - let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:12:9: 12:10 - let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:17:5: 32:6 - let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:6: 34:7 - let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:9: 34:10 - let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:12: 34:13 - let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:15: 34:16 + debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:12:8: 12:9 + let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:12:19: 12:43 + let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:18:5: 33:6 + let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:6: 35:7 + let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:9: 35:10 + let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:12: 35:13 + let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:15: 35:16 scope 1 { - debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:12:9: 12:10 - let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:14:9: 14:10 scope 2 { - debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:13:9: 13:10 - let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:14:9: 14:10 + debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:14:9: 14:10 + let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:15:9: 15:10 scope 3 { - debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:14:9: 14:10 - let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:16:9: 16:10 scope 4 { - debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:16:9: 16:10 } } } } bb0: { - StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:12:9: 12:10 - StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 - StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:14:9: 14:10 - StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:15:9: 15:10 - StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6 -- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10 -+ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22 -+ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21 -+ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22 -+ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21 -+ goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10 + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:14:9: 14:10 + StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:16:9: 16:10 + StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 +- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 ++ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 ++ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 ++ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:22 ++ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:23:13: 23:21 ++ goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 } bb1: { - _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:26:13: 26:21 - _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:27:13: 27:22 - _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:28:13: 28:22 - _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:29:13: 29:21 - goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6 + _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:27:13: 27:21 + _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:28:13: 28:22 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:29:13: 29:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:30:13: 30:21 + goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 } bb2: { - _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22 - _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21 - _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22 - _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21 - goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6 + _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 + _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:23:13: 23:21 + goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 } bb3: { - StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:32:6: 32:7 - StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:34:6: 34:7 - _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:34:6: 34:7 - StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:34:9: 34:10 - _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:34:9: 34:10 - StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:34:12: 34:13 - _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:34:12: 34:13 - StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:34:15: 34:16 - _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:34:15: 34:16 - (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - return; // scope 0 at $DIR/matches_reduce_branches.rs:35:2: 35:2 + StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:33:6: 33:7 + StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:35:6: 35:7 + _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:35:6: 35:7 + StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:35:9: 35:10 + _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:35:9: 35:10 + StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:35:12: 35:13 + _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:35:12: 35:13 + StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:35:15: 35:16 + _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:35:15: 35:16 + (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:36:2: 36:2 } } diff --git a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff index 3f01719e01bfc..648cf241cbaba 100644 --- a/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.bar.MatchBranchSimplification.64bit.diff @@ -2,83 +2,83 @@ + // MIR for `bar` after MatchBranchSimplification fn bar(_1: i32) -> (bool, bool, bool, bool) { - debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:11:8: 11:9 - let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:11:19: 11:43 - let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:12:9: 12:10 - let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:17:5: 32:6 - let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:6: 34:7 - let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:9: 34:10 - let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:12: 34:13 - let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:34:15: 34:16 + debug i => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:12:8: 12:9 + let mut _0: (bool, bool, bool, bool); // return place in scope 0 at $DIR/matches_reduce_branches.rs:12:19: 12:43 + let _2: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + let _6: (); // in scope 0 at $DIR/matches_reduce_branches.rs:18:5: 33:6 + let mut _7: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:6: 35:7 + let mut _8: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:9: 35:10 + let mut _9: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:12: 35:13 + let mut _10: bool; // in scope 0 at $DIR/matches_reduce_branches.rs:35:15: 35:16 scope 1 { - debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:12:9: 12:10 - let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + debug a => _2; // in scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + let _3: bool; // in scope 1 at $DIR/matches_reduce_branches.rs:14:9: 14:10 scope 2 { - debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:13:9: 13:10 - let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:14:9: 14:10 + debug b => _3; // in scope 2 at $DIR/matches_reduce_branches.rs:14:9: 14:10 + let _4: bool; // in scope 2 at $DIR/matches_reduce_branches.rs:15:9: 15:10 scope 3 { - debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:14:9: 14:10 - let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + debug c => _4; // in scope 3 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + let _5: bool; // in scope 3 at $DIR/matches_reduce_branches.rs:16:9: 16:10 scope 4 { - debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + debug d => _5; // in scope 4 at $DIR/matches_reduce_branches.rs:16:9: 16:10 } } } } bb0: { - StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:12:9: 12:10 - StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:13:9: 13:10 - StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:14:9: 14:10 - StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:15:9: 15:10 - StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6 -- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10 -+ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22 -+ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21 -+ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22 -+ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21 -+ goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:9: 18:10 + StorageLive(_2); // scope 0 at $DIR/matches_reduce_branches.rs:13:9: 13:10 + StorageLive(_3); // scope 1 at $DIR/matches_reduce_branches.rs:14:9: 14:10 + StorageLive(_4); // scope 2 at $DIR/matches_reduce_branches.rs:15:9: 15:10 + StorageLive(_5); // scope 3 at $DIR/matches_reduce_branches.rs:16:9: 16:10 + StorageLive(_6); // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 +- switchInt(_1) -> [7_i32: bb2, otherwise: bb1]; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 ++ _2 = Ne(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 ++ _3 = Eq(_1, const 7_i32); // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 ++ _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:22 ++ _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:23:13: 23:21 ++ goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:19:9: 19:10 } bb1: { - _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:26:13: 26:21 - _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:27:13: 27:22 - _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:28:13: 28:22 - _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:29:13: 29:21 - goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6 + _2 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:27:13: 27:21 + _3 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:28:13: 28:22 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:29:13: 29:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:30:13: 30:21 + goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 } bb2: { - _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:19:13: 19:22 - _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:21 - _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:22 - _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:21 - goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:17:5: 32:6 + _2 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:20:13: 20:22 + _3 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:21:13: 21:21 + _4 = const false; // scope 4 at $DIR/matches_reduce_branches.rs:22:13: 22:22 + _5 = const true; // scope 4 at $DIR/matches_reduce_branches.rs:23:13: 23:21 + goto -> bb3; // scope 4 at $DIR/matches_reduce_branches.rs:18:5: 33:6 } bb3: { - StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:32:6: 32:7 - StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:34:6: 34:7 - _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:34:6: 34:7 - StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:34:9: 34:10 - _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:34:9: 34:10 - StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:34:12: 34:13 - _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:34:12: 34:13 - StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:34:15: 34:16 - _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:34:15: 34:16 - (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:34:5: 34:17 - StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:34:16: 34:17 - StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:35:1: 35:2 - return; // scope 0 at $DIR/matches_reduce_branches.rs:35:2: 35:2 + StorageDead(_6); // scope 4 at $DIR/matches_reduce_branches.rs:33:6: 33:7 + StorageLive(_7); // scope 4 at $DIR/matches_reduce_branches.rs:35:6: 35:7 + _7 = _2; // scope 4 at $DIR/matches_reduce_branches.rs:35:6: 35:7 + StorageLive(_8); // scope 4 at $DIR/matches_reduce_branches.rs:35:9: 35:10 + _8 = _3; // scope 4 at $DIR/matches_reduce_branches.rs:35:9: 35:10 + StorageLive(_9); // scope 4 at $DIR/matches_reduce_branches.rs:35:12: 35:13 + _9 = _4; // scope 4 at $DIR/matches_reduce_branches.rs:35:12: 35:13 + StorageLive(_10); // scope 4 at $DIR/matches_reduce_branches.rs:35:15: 35:16 + _10 = _5; // scope 4 at $DIR/matches_reduce_branches.rs:35:15: 35:16 + (_0.0: bool) = move _7; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + (_0.1: bool) = move _8; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + (_0.2: bool) = move _9; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + (_0.3: bool) = move _10; // scope 4 at $DIR/matches_reduce_branches.rs:35:5: 35:17 + StorageDead(_10); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_9); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_8); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_7); // scope 4 at $DIR/matches_reduce_branches.rs:35:16: 35:17 + StorageDead(_5); // scope 3 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + StorageDead(_4); // scope 2 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + StorageDead(_3); // scope 1 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:36:1: 36:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:36:2: 36:2 } } diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff index 41f36036a18b9..a52abfb1a727d 100644 --- a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.32bit.diff @@ -2,17 +2,17 @@ + // MIR for `foo` after MatchBranchSimplification fn foo(_1: Option<()>) -> () { - debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:5:8: 5:11 - let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:5:25: 5:25 + debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:6:8: 6:11 + let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:6:25: 6:25 let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 + let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 bb0: { StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 -- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 + _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 +- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 + _2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL -+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 ++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 } bb1: { @@ -26,17 +26,17 @@ } bb3: { - switchInt(_2) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/matches_reduce_branches.rs:6:5: 8:6 + switchInt(_2) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6 } bb4: { - _0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:6:5: 8:6 - goto -> bb5; // scope 0 at $DIR/matches_reduce_branches.rs:6:5: 8:6 + _0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6 + goto -> bb5; // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6 } bb5: { - StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:9:1: 9:2 - return; // scope 0 at $DIR/matches_reduce_branches.rs:9:2: 9:2 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:10:1: 10:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:10:2: 10:2 } } diff --git a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff index 41f36036a18b9..a52abfb1a727d 100644 --- a/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff +++ b/src/test/mir-opt/matches_reduce_branches.foo.MatchBranchSimplification.64bit.diff @@ -2,17 +2,17 @@ + // MIR for `foo` after MatchBranchSimplification fn foo(_1: Option<()>) -> () { - debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:5:8: 5:11 - let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:5:25: 5:25 + debug bar => _1; // in scope 0 at $DIR/matches_reduce_branches.rs:6:8: 6:11 + let mut _0: (); // return place in scope 0 at $DIR/matches_reduce_branches.rs:6:25: 6:25 let mut _2: bool; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 + let mut _3: isize; // in scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 bb0: { StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 -- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 + _3 = discriminant(_1); // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 +- switchInt(move _3) -> [0_isize: bb2, otherwise: bb1]; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 + _2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL -+ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:6:22: 6:26 ++ goto -> bb3; // scope 0 at $DIR/matches_reduce_branches.rs:7:22: 7:26 } bb1: { @@ -26,17 +26,17 @@ } bb3: { - switchInt(_2) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/matches_reduce_branches.rs:6:5: 8:6 + switchInt(_2) -> [false: bb4, otherwise: bb5]; // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6 } bb4: { - _0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:6:5: 8:6 - goto -> bb5; // scope 0 at $DIR/matches_reduce_branches.rs:6:5: 8:6 + _0 = const (); // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6 + goto -> bb5; // scope 0 at $DIR/matches_reduce_branches.rs:7:5: 9:6 } bb5: { - StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:9:1: 9:2 - return; // scope 0 at $DIR/matches_reduce_branches.rs:9:2: 9:2 + StorageDead(_2); // scope 0 at $DIR/matches_reduce_branches.rs:10:1: 10:2 + return; // scope 0 at $DIR/matches_reduce_branches.rs:10:2: 10:2 } } diff --git a/src/test/mir-opt/matches_reduce_branches.rs b/src/test/mir-opt/matches_reduce_branches.rs index ebc88d2fbd1da..54b79a84263fe 100644 --- a/src/test/mir-opt/matches_reduce_branches.rs +++ b/src/test/mir-opt/matches_reduce_branches.rs @@ -1,3 +1,4 @@ +// compile-flags: -Zunsound-mir-opts // EMIT_MIR_FOR_EACH_BIT_WIDTH // EMIT_MIR matches_reduce_branches.foo.MatchBranchSimplification.diff // EMIT_MIR matches_reduce_branches.bar.MatchBranchSimplification.diff diff --git a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff index 7a625966619e9..39830946aebd6 100644 --- a/src/test/mir-opt/not_equal_false.opt.InstCombine.diff +++ b/src/test/mir-opt/not_equal_false.opt.InstCombine.diff @@ -12,36 +12,57 @@ bb0: { StorageLive(_2); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _3 = discriminant(_1); // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 - _2 = Eq(_3, const 0_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 + switchInt(move _3) -> [0_isize: bb6, otherwise: bb5]; // scope 0 at $DIR/not_equal_false.rs:4:17: 4:21 } bb1: { _0 = const true; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 - goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 } bb2: { + _0 = const false; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + goto -> bb4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + } + + bb3: { StorageLive(_4); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL _5 = discriminant(_1); // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 - _4 = Eq(_5, const 1_isize); // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - goto -> bb5; // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 + switchInt(move _5) -> [1_isize: bb9, otherwise: bb8]; // scope 0 at $DIR/not_equal_false.rs:4:38: 4:45 } - bb3: { + bb4: { StorageDead(_4); // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46 StorageDead(_2); // scope 0 at $DIR/not_equal_false.rs:4:45: 4:46 return; // scope 0 at $DIR/not_equal_false.rs:5:2: 5:2 } - bb4: { - switchInt(move _2) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + bb5: { + _2 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb7; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL } - bb5: { -- _0 = Ne(_4, const false); // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 -+ _0 = _4; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 - goto -> bb3; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + bb6: { + _2 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb7; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb7: { + switchInt(move _2) -> [false: bb3, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 + } + + bb8: { + _4 = const false; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb10; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb9: { + _4 = const true; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + goto -> bb10; // scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + } + + bb10: { + switchInt(move _4) -> [false: bb2, otherwise: bb1]; // scope 0 at $DIR/not_equal_false.rs:4:5: 4:46 } } From 1614b7fbac75df8807ac6083559bca9a261128df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 13 Oct 2020 21:42:59 -0700 Subject: [PATCH 08/11] Do not ICE with TraitPredicates containing [type error] Fix #77919. --- .../src/traits/select/mod.rs | 19 +++++--- src/test/ui/issues/issue-77919.rs | 13 ++++++ src/test/ui/issues/issue-77919.stderr | 46 +++++++++++++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/issues/issue-77919.rs create mode 100644 src/test/ui/issues/issue-77919.stderr diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index 114dc79c44f50..f930734f5b595 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1951,12 +1951,19 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &predicate.subst(tcx, substs), &mut obligations, ); - obligations.push(Obligation { - cause: cause.clone(), - recursion_depth, - param_env, - predicate, - }); + if predicate.references_error() { + self.tcx().sess.delay_span_bug( + cause.span, + &format!("impl_or_trait_obligation with errors: {:?}", predicate), + ); + } else { + obligations.push(Obligation { + cause: cause.clone(), + recursion_depth, + param_env, + predicate, + }); + } } // We are performing deduplication here to avoid exponential blowups diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs new file mode 100644 index 0000000000000..9b04d5ee0008d --- /dev/null +++ b/src/test/ui/issues/issue-77919.rs @@ -0,0 +1,13 @@ +fn main() { + [1; >::VAL]; //~ ERROR evaluation of constant value failed +} +trait TypeVal { + const VAL: T; //~ ERROR any use of this value will cause an error +} +struct Five; +struct Multiply { + _n: PhantomData, //~ ERROR cannot find type `PhantomData` in this scope +} +impl TypeVal for Multiply where N: TypeVal {} +//~^ ERROR cannot find type `VAL` in this scope +//~| ERROR not all trait items implemented, missing: `VAL` diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr new file mode 100644 index 0000000000000..129af00644fff --- /dev/null +++ b/src/test/ui/issues/issue-77919.stderr @@ -0,0 +1,46 @@ +error[E0412]: cannot find type `PhantomData` in this scope + --> $DIR/issue-77919.rs:9:9 + | +LL | _n: PhantomData, + | ^^^^^^^^^^^ not found in this scope + | +help: consider importing this struct + | +LL | use std::marker::PhantomData; + | + +error[E0412]: cannot find type `VAL` in this scope + --> $DIR/issue-77919.rs:11:63 + | +LL | impl TypeVal for Multiply where N: TypeVal {} + | - ^^^ not found in this scope + | | + | help: you might be missing a type parameter: `, VAL` + +error[E0046]: not all trait items implemented, missing: `VAL` + --> $DIR/issue-77919.rs:11:1 + | +LL | const VAL: T; + | ------------- `VAL` from trait +... +LL | impl TypeVal for Multiply where N: TypeVal {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation + +error: any use of this value will cause an error + --> $DIR/issue-77919.rs:5:5 + | +LL | const VAL: T; + | ^^^^^^^^^^^^^ no MIR body is available for DefId(0:7 ~ issue_77919[317d]::TypeVal::VAL) + | + = note: `#[deny(const_err)]` on by default + +error[E0080]: evaluation of constant value failed + --> $DIR/issue-77919.rs:2:9 + | +LL | [1; >::VAL]; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + +error: aborting due to 5 previous errors + +Some errors have detailed explanations: E0046, E0080, E0412. +For more information about an error, try `rustc --explain E0046`. From cb3db707587adf03781cf286b980fc4e44080e9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 23 Oct 2020 12:51:06 -0700 Subject: [PATCH 09/11] review comments --- .../src/traits/codegen/mod.rs | 5 ++++- .../src/traits/select/mod.rs | 19 ++++++------------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/codegen/mod.rs b/compiler/rustc_trait_selection/src/traits/codegen/mod.rs index dd7ea55cc1043..6b1ed5f493c1c 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen/mod.rs @@ -118,7 +118,10 @@ where // contains unbound type parameters. It could be a slight // optimization to stop iterating early. if let Err(errors) = fulfill_cx.select_all_or_error(infcx) { - bug!("Encountered errors `{:?}` resolving bounds after type-checking", errors); + infcx.tcx.sess.delay_span_bug( + rustc_span::DUMMY_SP, + &format!("Encountered errors `{:?}` resolving bounds after type-checking", errors), + ); } let result = infcx.resolve_vars_if_possible(result); diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs index f930734f5b595..114dc79c44f50 100644 --- a/compiler/rustc_trait_selection/src/traits/select/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs @@ -1951,19 +1951,12 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { &predicate.subst(tcx, substs), &mut obligations, ); - if predicate.references_error() { - self.tcx().sess.delay_span_bug( - cause.span, - &format!("impl_or_trait_obligation with errors: {:?}", predicate), - ); - } else { - obligations.push(Obligation { - cause: cause.clone(), - recursion_depth, - param_env, - predicate, - }); - } + obligations.push(Obligation { + cause: cause.clone(), + recursion_depth, + param_env, + predicate, + }); } // We are performing deduplication here to avoid exponential blowups From be7032e4fe894f5dac5032bb2c35a495a3438217 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 27 Sep 2020 18:58:56 -0700 Subject: [PATCH 10/11] Tweak `if let` suggestion to be more liberal with suggestion and to not ICE Fix #77218. Fix #77238. --- compiler/rustc_typeck/src/check/expr.rs | 50 ++++++++++++---------- src/test/ui/issues/issue-77218.rs | 7 +++ src/test/ui/issues/issue-77218.stderr | 14 ++++++ src/test/ui/suggestions/if-let-typo.rs | 1 - src/test/ui/suggestions/if-let-typo.stderr | 18 +++----- 5 files changed, 56 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/issues/issue-77218.rs create mode 100644 src/test/ui/issues/issue-77218.stderr diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index af800eab67a5e..275f2ed7c8b8f 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -768,34 +768,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap(); let lhs_ty = self.check_expr(&lhs); let rhs_ty = self.check_expr(&rhs); - if self.can_coerce(lhs_ty, rhs_ty) { - if !lhs.is_syntactic_place_expr() { - // Do not suggest `if let x = y` as `==` is way more likely to be the intention. - if let hir::Node::Expr(hir::Expr { - kind: ExprKind::Match(_, _, hir::MatchSource::IfDesugar { .. }), - .. - }) = self.tcx.hir().get( - self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)), - ) { - // Likely `if let` intended. - err.span_suggestion_verbose( - expr.span.shrink_to_lo(), - "you might have meant to use pattern matching", - "let ".to_string(), - Applicability::MaybeIncorrect, - ); - } + let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) { + (Applicability::MachineApplicable, true) + } else { + (Applicability::MaybeIncorrect, false) + }; + if !lhs.is_syntactic_place_expr() { + // Do not suggest `if let x = y` as `==` is way more likely to be the intention. + if let hir::Node::Expr(hir::Expr { + kind: + ExprKind::Match( + _, + _, + hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar, + ), + .. + }) = self.tcx.hir().get( + self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)), + ) { + // Likely `if let` intended. + err.span_suggestion_verbose( + expr.span.shrink_to_lo(), + "you might have meant to use pattern matching", + "let ".to_string(), + applicability, + ); } + } + if eq { err.span_suggestion_verbose( *span, "you might have meant to compare for equality", "==".to_string(), - Applicability::MaybeIncorrect, + applicability, ); - } else { - // Do this to cause extra errors about the assignment. - let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); - let _ = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs)); } if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() { diff --git a/src/test/ui/issues/issue-77218.rs b/src/test/ui/issues/issue-77218.rs new file mode 100644 index 0000000000000..bc992c21dca5c --- /dev/null +++ b/src/test/ui/issues/issue-77218.rs @@ -0,0 +1,7 @@ +fn main() { + let value = [7u8]; + while Some(0) = value.get(0) { //~ ERROR mismatched types + //~^ NOTE expected `bool`, found `()` + //~| HELP you might have meant to use pattern matching + } +} diff --git a/src/test/ui/issues/issue-77218.stderr b/src/test/ui/issues/issue-77218.stderr new file mode 100644 index 0000000000000..eca44725eb258 --- /dev/null +++ b/src/test/ui/issues/issue-77218.stderr @@ -0,0 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/issue-77218.rs:3:11 + | +LL | while Some(0) = value.get(0) { + | ^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to use pattern matching + | +LL | while let Some(0) = value.get(0) { + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/suggestions/if-let-typo.rs b/src/test/ui/suggestions/if-let-typo.rs index c1e417b97f619..87def13c476c7 100644 --- a/src/test/ui/suggestions/if-let-typo.rs +++ b/src/test/ui/suggestions/if-let-typo.rs @@ -4,6 +4,5 @@ fn main() { if Some(x) = foo {} //~ ERROR cannot find value `x` in this scope if Some(foo) = bar {} //~ ERROR mismatched types if 3 = foo {} //~ ERROR mismatched types - //~^ ERROR mismatched types if Some(3) = foo {} //~ ERROR mismatched types } diff --git a/src/test/ui/suggestions/if-let-typo.stderr b/src/test/ui/suggestions/if-let-typo.stderr index bb2ea8cb4778a..d8e50cae55ad1 100644 --- a/src/test/ui/suggestions/if-let-typo.stderr +++ b/src/test/ui/suggestions/if-let-typo.stderr @@ -24,23 +24,19 @@ help: you might have meant to compare for equality LL | if Some(foo) == bar {} | ^^ -error[E0308]: mismatched types - --> $DIR/if-let-typo.rs:6:12 - | -LL | if 3 = foo {} - | ^^^ expected integer, found enum `Option` - | - = note: expected type `{integer}` - found enum `Option<{integer}>` - error[E0308]: mismatched types --> $DIR/if-let-typo.rs:6:8 | LL | if 3 = foo {} | ^^^^^^^ expected `bool`, found `()` + | +help: you might have meant to use pattern matching + | +LL | if let 3 = foo {} + | ^^^ error[E0308]: mismatched types - --> $DIR/if-let-typo.rs:8:8 + --> $DIR/if-let-typo.rs:7:8 | LL | if Some(3) = foo {} | ^^^^^^^^^^^^^ expected `bool`, found `()` @@ -54,7 +50,7 @@ help: you might have meant to compare for equality LL | if Some(3) == foo {} | ^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0308, E0425. For more information about an error, try `rustc --explain E0308`. From ec4ea4a976d9f0e187642833a515172f4d120c70 Mon Sep 17 00:00:00 2001 From: Jonas Schievink Date: Fri, 23 Oct 2020 23:52:06 +0200 Subject: [PATCH 11/11] Fix Ubuntu download URL --- src/ci/docker/host-x86_64/armhf-gnu/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile index 9fb5faf3ee0f4..9370f5debb5ea 100644 --- a/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile +++ b/src/ci/docker/host-x86_64/armhf-gnu/Dockerfile @@ -58,7 +58,7 @@ RUN curl https://www.busybox.net/downloads/busybox-1.21.1.tar.bz2 | tar xjf - && # Download the ubuntu rootfs, which we'll use as a chroot for all our tests. WORKDIR /tmp RUN mkdir rootfs/ubuntu -RUN curl http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04-core-armhf.tar.gz | \ +RUN curl http://cdimage.ubuntu.com/ubuntu-base/releases/16.04/release/ubuntu-base-16.04.6-base-armhf.tar.gz | \ tar xzf - -C rootfs/ubuntu && \ cd rootfs && mkdir proc sys dev etc etc/init.d