From cab607edcfe556343aa4fcb3de6229a790fc5e72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 31 Aug 2019 18:34:50 -0700 Subject: [PATCH 01/14] Emit a single error on if expr with expectation and no else clause --- src/librustc_typeck/check/_match.rs | 41 ++++++--- src/test/ui/if/if-without-else-as-fn-expr.rs | 6 -- .../ui/if/if-without-else-as-fn-expr.stderr | 83 ++----------------- src/test/ui/issues/issue-50577.rs | 1 - src/test/ui/issues/issue-50577.stderr | 15 +--- 5 files changed, 38 insertions(+), 108 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index efc37cc04b212..3983a3b820391 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -112,23 +112,36 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.diverges.set(pats_diverge); - let arm_ty = self.check_expr_with_expectation(&arm.body, expected); - all_arms_diverge &= self.diverges.get(); - - let span = expr.span; - - if source_if { + let arm_ty = if source_if { let then_expr = &arms[0].body; match (i, if_no_else) { - (0, _) => coercion.coerce(self, &self.misc(span), &arm.body, arm_ty), - (_, true) => self.if_fallback_coercion(span, then_expr, &mut coercion), + (0, _) => { + let arm_ty = self.check_expr_with_expectation(&arm.body, expected); + all_arms_diverge &= self.diverges.get(); + coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty); + arm_ty + } + (_, true) => { + if self.if_fallback_coercion(expr.span, then_expr, &mut coercion) { + tcx.types.err + } else { + let arm_ty = self.check_expr_with_expectation(&arm.body, expected); + all_arms_diverge &= self.diverges.get(); + arm_ty + } + } (_, _) => { + let arm_ty = self.check_expr_with_expectation(&arm.body, expected); + all_arms_diverge &= self.diverges.get(); let then_ty = prior_arm_ty.unwrap(); - let cause = self.if_cause(span, then_expr, &arm.body, then_ty, arm_ty); + let cause = self.if_cause(expr.span, then_expr, &arm.body, then_ty, arm_ty); coercion.coerce(self, &cause, &arm.body, arm_ty); + arm_ty } } } else { + let arm_ty = self.check_expr_with_expectation(&arm.body, expected); + all_arms_diverge &= self.diverges.get(); let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node { // Point at the block expr instead of the entire block blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span) @@ -139,7 +152,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // The reason for the first arm to fail is not that the match arms diverge, // but rather that there's a prior obligation that doesn't hold. 0 => (arm_span, ObligationCauseCode::BlockTailExpression(arm.body.hir_id)), - _ => (span, ObligationCauseCode::MatchExpressionArm { + _ => (expr.span, ObligationCauseCode::MatchExpressionArm { arm_span, source: match_src, prior_arms: other_arms.clone(), @@ -153,7 +166,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if other_arms.len() > 5 { other_arms.remove(0); } - } + arm_ty + }; prior_arm_ty = Some(arm_ty); } @@ -185,11 +199,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { span: Span, then_expr: &'tcx hir::Expr, coercion: &mut CoerceMany<'tcx, '_, rustc::hir::Arm>, - ) { + ) -> bool { // If this `if` expr is the parent's function return expr, // the cause of the type coercion is the return type, point at it. (#25228) let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span); let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse); + let mut error = false; coercion.coerce_forced_unit(self, &cause, &mut |err| { if let Some((span, msg)) = &ret_reason { err.span_label(*span, msg.as_str()); @@ -200,7 +215,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } err.note("`if` expressions without `else` evaluate to `()`"); err.help("consider adding an `else` block that evaluates to the expected type"); + error = true; }, ret_reason.is_none()); + error } fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, span: Span) -> Option<(Span, String)> { diff --git a/src/test/ui/if/if-without-else-as-fn-expr.rs b/src/test/ui/if/if-without-else-as-fn-expr.rs index 15892de83854c..826371be35f45 100644 --- a/src/test/ui/if/if-without-else-as-fn-expr.rs +++ b/src/test/ui/if/if-without-else-as-fn-expr.rs @@ -3,7 +3,6 @@ fn foo(bar: usize) -> usize { return 3; } //~^^^ ERROR if may be missing an else clause - //~| ERROR mismatched types [E0308] } fn foo2(bar: usize) -> usize { @@ -11,7 +10,6 @@ fn foo2(bar: usize) -> usize { return 3; }; //~^^^ ERROR if may be missing an else clause - //~| ERROR mismatched types [E0308] x } @@ -20,7 +18,6 @@ fn foo3(bar: usize) -> usize { 3 } //~^^^ ERROR if may be missing an else clause - //~| ERROR mismatched types [E0308] } fn foo_let(bar: usize) -> usize { @@ -28,7 +25,6 @@ fn foo_let(bar: usize) -> usize { return 3; } //~^^^ ERROR if may be missing an else clause - //~| ERROR mismatched types [E0308] } fn foo2_let(bar: usize) -> usize { @@ -36,7 +32,6 @@ fn foo2_let(bar: usize) -> usize { return 3; }; //~^^^ ERROR if may be missing an else clause - //~| ERROR mismatched types [E0308] x } @@ -45,7 +40,6 @@ fn foo3_let(bar: usize) -> usize { 3 } //~^^^ ERROR if may be missing an else clause - //~| ERROR mismatched types [E0308] } // FIXME(60254): deduplicate first error in favor of second. diff --git a/src/test/ui/if/if-without-else-as-fn-expr.stderr b/src/test/ui/if/if-without-else-as-fn-expr.stderr index 06600b1cb9aea..b49c2aa6319df 100644 --- a/src/test/ui/if/if-without-else-as-fn-expr.stderr +++ b/src/test/ui/if/if-without-else-as-fn-expr.stderr @@ -1,14 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/if-without-else-as-fn-expr.rs:2:5 - | -LL | / if bar % 5 == 0 { -LL | | return 3; -LL | | } - | |_____^ expected usize, found () - | - = note: expected type `usize` - found type `()` - error[E0317]: if may be missing an else clause --> $DIR/if-without-else-as-fn-expr.rs:2:5 | @@ -24,20 +13,8 @@ LL | | } = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type -error[E0308]: mismatched types - --> $DIR/if-without-else-as-fn-expr.rs:10:20 - | -LL | let x: usize = if bar % 5 == 0 { - | ____________________^ -LL | | return 3; -LL | | }; - | |_____^ expected usize, found () - | - = note: expected type `usize` - found type `()` - error[E0317]: if may be missing an else clause - --> $DIR/if-without-else-as-fn-expr.rs:10:20 + --> $DIR/if-without-else-as-fn-expr.rs:9:20 | LL | let x: usize = if bar % 5 == 0 { | _________-__________^ @@ -52,19 +29,8 @@ LL | | }; = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type -error[E0308]: mismatched types - --> $DIR/if-without-else-as-fn-expr.rs:19:5 - | -LL | / if bar % 5 == 0 { -LL | | 3 -LL | | } - | |_____^ expected usize, found () - | - = note: expected type `usize` - found type `()` - error[E0317]: if may be missing an else clause - --> $DIR/if-without-else-as-fn-expr.rs:19:5 + --> $DIR/if-without-else-as-fn-expr.rs:17:5 | LL | fn foo3(bar: usize) -> usize { | ----- expected `usize` because of this return type @@ -78,19 +44,8 @@ LL | | } = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type -error[E0308]: mismatched types - --> $DIR/if-without-else-as-fn-expr.rs:27:5 - | -LL | / if let 0 = 1 { -LL | | return 3; -LL | | } - | |_____^ expected usize, found () - | - = note: expected type `usize` - found type `()` - error[E0317]: if may be missing an else clause - --> $DIR/if-without-else-as-fn-expr.rs:27:5 + --> $DIR/if-without-else-as-fn-expr.rs:24:5 | LL | fn foo_let(bar: usize) -> usize { | ----- expected `usize` because of this return type @@ -104,20 +59,8 @@ LL | | } = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type -error[E0308]: mismatched types - --> $DIR/if-without-else-as-fn-expr.rs:35:20 - | -LL | let x: usize = if let 0 = 1 { - | ____________________^ -LL | | return 3; -LL | | }; - | |_____^ expected usize, found () - | - = note: expected type `usize` - found type `()` - error[E0317]: if may be missing an else clause - --> $DIR/if-without-else-as-fn-expr.rs:35:20 + --> $DIR/if-without-else-as-fn-expr.rs:31:20 | LL | let x: usize = if let 0 = 1 { | _________-__________^ @@ -132,19 +75,8 @@ LL | | }; = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type -error[E0308]: mismatched types - --> $DIR/if-without-else-as-fn-expr.rs:44:5 - | -LL | / if let 0 = 1 { -LL | | 3 -LL | | } - | |_____^ expected usize, found () - | - = note: expected type `usize` - found type `()` - error[E0317]: if may be missing an else clause - --> $DIR/if-without-else-as-fn-expr.rs:44:5 + --> $DIR/if-without-else-as-fn-expr.rs:39:5 | LL | fn foo3_let(bar: usize) -> usize { | ----- expected `usize` because of this return type @@ -158,7 +90,6 @@ LL | | } = note: `if` expressions without `else` evaluate to `()` = help: consider adding an `else` block that evaluates to the expected type -error: aborting due to 12 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0308, E0317. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0317`. diff --git a/src/test/ui/issues/issue-50577.rs b/src/test/ui/issues/issue-50577.rs index bf892a8daa27f..f0f1dc6c28667 100644 --- a/src/test/ui/issues/issue-50577.rs +++ b/src/test/ui/issues/issue-50577.rs @@ -2,6 +2,5 @@ fn main() { enum Foo { Drop = assert_eq!(1, 1) //~^ ERROR if may be missing an else clause - //~| ERROR mismatched types [E0308] } } diff --git a/src/test/ui/issues/issue-50577.stderr b/src/test/ui/issues/issue-50577.stderr index 413c8c5c80b52..0c3ba2ea4f94d 100644 --- a/src/test/ui/issues/issue-50577.stderr +++ b/src/test/ui/issues/issue-50577.stderr @@ -1,13 +1,3 @@ -error[E0308]: mismatched types - --> $DIR/issue-50577.rs:3:16 - | -LL | Drop = assert_eq!(1, 1) - | ^^^^^^^^^^^^^^^^ expected isize, found () - | - = note: expected type `isize` - found type `()` - = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) - error[E0317]: if may be missing an else clause --> $DIR/issue-50577.rs:3:16 | @@ -23,7 +13,6 @@ LL | Drop = assert_eq!(1, 1) = help: consider adding an `else` block that evaluates to the expected type = note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info) -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0308, E0317. -For more information about an error, try `rustc --explain E0308`. +For more information about this error, try `rustc --explain E0317`. From aae2b245e4c3958ca37d6eaa58b89d955d0b66e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sat, 31 Aug 2019 18:42:13 -0700 Subject: [PATCH 02/14] deduplicate code --- src/librustc_typeck/check/_match.rs | 40 ++++++++++++----------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 3983a3b820391..63d059bdf2a80 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -112,36 +112,31 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } self.diverges.set(pats_diverge); - let arm_ty = if source_if { + let arm_ty = if source_if && if_no_else && i != 0 && self.if_fallback_coercion( + expr.span, + &arms[0].body, + &mut coercion, + ) { + tcx.types.err + } else { + // Only call this if this is not an `if` expr with an expected type and no `else` + // clause to avoid duplicated type errors. (#60254) + let arm_ty = self.check_expr_with_expectation(&arm.body, expected); + all_arms_diverge &= self.diverges.get(); + arm_ty + }; + if source_if { let then_expr = &arms[0].body; match (i, if_no_else) { - (0, _) => { - let arm_ty = self.check_expr_with_expectation(&arm.body, expected); - all_arms_diverge &= self.diverges.get(); - coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty); - arm_ty - } - (_, true) => { - if self.if_fallback_coercion(expr.span, then_expr, &mut coercion) { - tcx.types.err - } else { - let arm_ty = self.check_expr_with_expectation(&arm.body, expected); - all_arms_diverge &= self.diverges.get(); - arm_ty - } - } + (0, _) => coercion.coerce(self, &self.misc(expr.span), &arm.body, arm_ty), + (_, true) => {} // Handled above to avoid duplicated type errors (#60254). (_, _) => { - let arm_ty = self.check_expr_with_expectation(&arm.body, expected); - all_arms_diverge &= self.diverges.get(); let then_ty = prior_arm_ty.unwrap(); let cause = self.if_cause(expr.span, then_expr, &arm.body, then_ty, arm_ty); coercion.coerce(self, &cause, &arm.body, arm_ty); - arm_ty } } } else { - let arm_ty = self.check_expr_with_expectation(&arm.body, expected); - all_arms_diverge &= self.diverges.get(); let arm_span = if let hir::ExprKind::Block(blk, _) = &arm.body.node { // Point at the block expr instead of the entire block blk.expr.as_ref().map(|e| e.span).unwrap_or(arm.body.span) @@ -166,8 +161,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { if other_arms.len() > 5 { other_arms.remove(0); } - arm_ty - }; + } prior_arm_ty = Some(arm_ty); } From a9ce33c059d0a91fb12a79d75aa1a868d76bf6f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 1 Sep 2019 02:22:42 -0700 Subject: [PATCH 03/14] Account for arbitrary self types in E0599 --- src/librustc/ty/context.rs | 18 +++++ src/librustc_typeck/check/expr.rs | 72 +++++++++++++------ src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/suggest.rs | 9 +-- src/librustc_typeck/check/mod.rs | 2 +- .../no-method-suggested-traits.stderr | 8 +++ .../point-at-arbitrary-self-type-method.rs | 9 +++ ...point-at-arbitrary-self-type-method.stderr | 15 ++++ ...int-at-arbitrary-self-type-trait-method.rs | 10 +++ ...at-arbitrary-self-type-trait-method.stderr | 18 +++++ src/test/ui/traits/trait-item-privacy.stderr | 7 ++ 11 files changed, 144 insertions(+), 26 deletions(-) create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-method.rs create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-method.stderr create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs create mode 100644 src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index e240e0df8b948..f355e231914d2 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2402,6 +2402,24 @@ impl<'tcx> TyCtxt<'tcx> { self.mk_generic_adt(def_id, ty) } + #[inline] + pub fn mk_pin(self, ty: Ty<'tcx>) -> Ty<'tcx> { + let def_id = self.require_lang_item(lang_items::PinTypeLangItem, None); + self.mk_generic_adt(def_id, ty) + } + + #[inline] + pub fn mk_rc(self, ty: Ty<'tcx>) -> Ty<'tcx> { + let def_id = self.require_lang_item(lang_items::Rc, None); + self.mk_generic_adt(def_id, ty) + } + + #[inline] + pub fn mk_arc(self, ty: Ty<'tcx>) -> Ty<'tcx> { + let def_id = self.require_lang_item(lang_items::Arc, None); + self.mk_generic_adt(def_id, ty) + } + #[inline] pub fn mk_maybe_uninit(self, ty: Ty<'tcx>) -> Ty<'tcx> { let def_id = self.require_lang_item(lang_items::MaybeUninitLangItem, None); diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index a53fb12367d0e..efff8bcdacbcf 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -12,7 +12,7 @@ use crate::check::fatally_break_rust; use crate::check::report_unexpected_variant_res; use crate::check::Needs; use crate::check::TupleArgumentsFlag::DontTupleArguments; -use crate::check::method::SelfSource; +use crate::check::method::{probe, SelfSource}; use crate::util::common::ErrorReported; use crate::util::nodemap::FxHashMap; use crate::astconv::AstConv as _; @@ -775,35 +775,65 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // no need to check for bot/err -- callee does that let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t); - let method = match self.lookup_method(rcvr_t, - segment, - span, - expr, - rcvr) { + let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| { + if let Ok(pick) = self.lookup_probe( + span, + segment.ident, + new_rcvr_t, + rcvr, + probe::ProbeScope::AllTraits, + ) { + err.span_label( + pick.item.ident.span, + &format!("the method is available for `{}` here", new_rcvr_t), + ); + } + }; + + let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) { Ok(method) => { self.write_method_call(expr.hir_id, method); Ok(method) } Err(error) => { if segment.ident.name != kw::Invalid { - self.report_method_error(span, - rcvr_t, - segment.ident, - SelfSource::MethodCall(rcvr), - error, - Some(args)); + if let Some(mut err) = self.report_method_error( + span, + rcvr_t, + segment.ident, + SelfSource::MethodCall(rcvr), + error, + Some(args), + ) { + if let ty::Adt(..) = rcvr_t.sty { + // Try alternative arbitrary self types that could fulfill this call. + // FIXME: probe for all types that *could* be arbitrary self-types, not + // just this whitelist. + let box_rcvr_t = self.tcx.mk_box(rcvr_t); + try_alt_rcvr(&mut err, box_rcvr_t); + let pin_rcvr_t = self.tcx.mk_pin(rcvr_t); + try_alt_rcvr(&mut err, pin_rcvr_t); + let arc_rcvr_t = self.tcx.mk_arc(rcvr_t); + try_alt_rcvr(&mut err, arc_rcvr_t); + let rc_rcvr_t = self.tcx.mk_rc(rcvr_t); + try_alt_rcvr(&mut err, rc_rcvr_t); + } + err.emit(); + } } Err(()) } }; // Call the generic checker. - self.check_method_argument_types(span, - expr.span, - method, - &args[1..], - DontTupleArguments, - expected) + self.check_method_argument_types( + span, + expr.span, + method, + &args[1..], + DontTupleArguments, + expected, + ) } fn check_expr_cast( @@ -1466,8 +1496,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let struct_variant_def = def.non_enum_variant(); let field_names = self.available_field_names(struct_variant_def); if !field_names.is_empty() { - err.note(&format!("available fields are: {}", - self.name_series_display(field_names))); + err.note(&format!( + "available fields are: {}", + self.name_series_display(field_names), + )); } } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index a7e4f8e5c6289..1509c0f8a2196 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -245,7 +245,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { Ok(result.callee) } - fn lookup_probe( + pub fn lookup_probe( &self, span: Span, method_name: ast::Ident, diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 440e7e5d0e314..72e6f59715960 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -69,12 +69,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { source: SelfSource<'b>, error: MethodError<'tcx>, args: Option<&'tcx [hir::Expr]>, - ) { + ) -> Option> { let orig_span = span; let mut span = span; // Avoid suggestions when we don't know what's going on. if rcvr_ty.references_error() { - return; + return None; } let print_disambiguation_help = | @@ -314,7 +314,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { _ => {} } err.emit(); - return; + return None; } else { span = item_name.span; let mut err = struct_span_err!( @@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ); } - err.emit(); + return Some(err); } MethodError::Ambiguity(sources) => { @@ -573,6 +573,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { bug!("no return type expectations but got BadReturnType") } } + None } fn suggest_use_candidates(&self, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index a80550486d627..2d9cacea68f31 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3580,7 +3580,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { SelfSource::QPath(qself), error, None, - ); + ).map(|mut e| e.emit()); } result }); diff --git a/src/test/ui/impl-trait/no-method-suggested-traits.stderr b/src/test/ui/impl-trait/no-method-suggested-traits.stderr index d980d7cccadd5..002b60f9f258d 100644 --- a/src/test/ui/impl-trait/no-method-suggested-traits.stderr +++ b/src/test/ui/impl-trait/no-method-suggested-traits.stderr @@ -49,6 +49,14 @@ LL | use foo::Bar; error[E0599]: no method named `method` found for type `std::rc::Rc<&mut std::boxed::Box<&char>>` in the current scope --> $DIR/no-method-suggested-traits.rs:32:43 | +LL | fn method(&self) {} + | ------ + | | + | the method is available for `std::boxed::Box>>` here + | the method is available for `std::pin::Pin>>` here + | the method is available for `std::sync::Arc>>` here + | the method is available for `std::rc::Rc>>` here +... LL | std::rc::Rc::new(&mut Box::new(&'a')).method(); | ^^^^^^ | diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.rs b/src/test/ui/self/point-at-arbitrary-self-type-method.rs new file mode 100644 index 0000000000000..0f7deeacad292 --- /dev/null +++ b/src/test/ui/self/point-at-arbitrary-self-type-method.rs @@ -0,0 +1,9 @@ +struct A; + +impl A { + fn foo(self: Box) {} +} + +fn main() { + A.foo(); //~ ERROR E0599 +} diff --git a/src/test/ui/self/point-at-arbitrary-self-type-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr new file mode 100644 index 0000000000000..06dad7caa6735 --- /dev/null +++ b/src/test/ui/self/point-at-arbitrary-self-type-method.stderr @@ -0,0 +1,15 @@ +error[E0599]: no method named `foo` found for type `A` in the current scope + --> $DIR/point-at-arbitrary-self-type-method.rs:8:7 + | +LL | struct A; + | --------- method `foo` not found for this +... +LL | fn foo(self: Box) {} + | --- the method is available for `std::boxed::Box` here +... +LL | A.foo(); + | ^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs new file mode 100644 index 0000000000000..53d992771186f --- /dev/null +++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.rs @@ -0,0 +1,10 @@ +trait B { fn foo(self: Box); } +struct A; + +impl B for A { + fn foo(self: Box) {} +} + +fn main() { + A.foo() //~ ERROR E0599 +} diff --git a/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr new file mode 100644 index 0000000000000..90cd3b8074580 --- /dev/null +++ b/src/test/ui/self/point-at-arbitrary-self-type-trait-method.stderr @@ -0,0 +1,18 @@ +error[E0599]: no method named `foo` found for type `A` in the current scope + --> $DIR/point-at-arbitrary-self-type-trait-method.rs:9:7 + | +LL | trait B { fn foo(self: Box); } + | --- the method is available for `std::boxed::Box` here +LL | struct A; + | --------- method `foo` not found for this +... +LL | A.foo() + | ^^^ + | + = help: items from traits can only be used if the trait is implemented and in scope + = note: the following trait defines an item `foo`, perhaps you need to implement it: + candidate #1: `B` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0599`. diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index de699a69fa8bc..ce2919c8e7741 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -17,6 +17,13 @@ error[E0599]: no method named `b` found for type `S` in the current scope LL | struct S; | --------- method `b` not found for this ... +LL | fn b(&self) { } + | - + | | + | the method is available for `std::boxed::Box` here + | the method is available for `std::sync::Arc` here + | the method is available for `std::rc::Rc` here +... LL | S.b(); | ^ | From 84ccbe2076cf37bc13c32a89ccc57a57281b8708 Mon Sep 17 00:00:00 2001 From: Philipp Hansch Date: Sun, 1 Sep 2019 12:15:33 +0200 Subject: [PATCH 04/14] librustc_errors: Extract sugg/subst handling into method An initial refactoring before working on #61809. This moves the whole block into a method so that it can be reused in the annotate-snippet output. It's already used in the new emitter, but there's no UI tests with suggestions included in this PR. A first look at some UI tests with suggestions showed that there's some more work to do in [annotate-snippet-rs][annotate-snippet-rs] before the new output is closer to the current one. --- .../annotate_snippet_emitter_writer.rs | 4 +- src/librustc_errors/emitter.rs | 40 ++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/src/librustc_errors/annotate_snippet_emitter_writer.rs b/src/librustc_errors/annotate_snippet_emitter_writer.rs index 255af3122e70c..3bed5d81dc514 100644 --- a/src/librustc_errors/annotate_snippet_emitter_writer.rs +++ b/src/librustc_errors/annotate_snippet_emitter_writer.rs @@ -30,10 +30,8 @@ pub struct AnnotateSnippetEmitterWriter { impl Emitter for AnnotateSnippetEmitterWriter { /// The entry point for the diagnostics generation fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) { - let primary_span = db.span.clone(); let children = db.children.clone(); - // FIXME(#59346): Collect suggestions (see emitter.rs) - let suggestions: &[_] = &[]; + let (primary_span, suggestions) = self.primary_span_formatted(&db); // FIXME(#59346): Add `fix_multispans_in_std_macros` function from emitter.rs diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 77d373e7a8ca8..0a9c927ef40a1 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -191,16 +191,25 @@ pub trait Emitter { fn should_show_explain(&self) -> bool { true } -} -impl Emitter for EmitterWriter { - fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) { + /// Formats the substitutions of the primary_span + /// + /// The are a lot of conditions to this method, but in short: + /// + /// * If the current `Diagnostic` has only one visible `CodeSuggestion`, + /// we format the `help` suggestion depending on the content of the + /// substitutions. In that case, we return the modified span only. + /// + /// * If the current `Diagnostic` has multiple suggestions, + /// we return the original `primary_span` and the original suggestions. + fn primary_span_formatted<'a>( + &mut self, + db: &'a DiagnosticBuilder<'_> + ) -> (MultiSpan, &'a [CodeSuggestion]) { let mut primary_span = db.span.clone(); - let mut children = db.children.clone(); - let mut suggestions: &[_] = &[]; - if let Some((sugg, rest)) = db.suggestions.split_first() { if rest.is_empty() && + // ^ if there is only one suggestion // don't display multi-suggestions as labels sugg.substitutions.len() == 1 && // don't display multipart suggestions as labels @@ -216,21 +225,34 @@ impl Emitter for EmitterWriter { { let substitution = &sugg.substitutions[0].parts[0].snippet.trim(); let msg = if substitution.len() == 0 || sugg.style.hide_inline() { - // This substitution is only removal or we explicitly don't want to show the - // code inline, don't show it + // This substitution is only removal OR we explicitly don't want to show the + // code inline (`hide_inline`). Therefore, we don't show the substitution. format!("help: {}", sugg.msg) } else { + // Show the default suggestion text with the substitution format!("help: {}: `{}`", sugg.msg, substitution) }; primary_span.push_span_label(sugg.substitutions[0].parts[0].span, msg); + + // We return only the modified primary_span + (primary_span, &[]) } else { // if there are multiple suggestions, print them all in full // to be consistent. We could try to figure out if we can // make one (or the first one) inline, but that would give // undue importance to a semi-random suggestion - suggestions = &db.suggestions; + (primary_span, &db.suggestions) } + } else { + (primary_span, &db.suggestions) } + } +} + +impl Emitter for EmitterWriter { + fn emit_diagnostic(&mut self, db: &DiagnosticBuilder<'_>) { + let mut children = db.children.clone(); + let (mut primary_span, suggestions) = self.primary_span_formatted(&db); self.fix_multispans_in_std_macros(&mut primary_span, &mut children, From 35c9e5f1229d8b634ebd98c49e35c74e237e17f7 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Sun, 1 Sep 2019 22:05:50 +0900 Subject: [PATCH 05/14] Fix const_err with `-(-0.0)` --- src/librustc_mir/transform/const_prop.rs | 14 +------------- src/test/ui/consts/const-err2.rs | 1 - src/test/ui/consts/const-err2.stderr | 20 +++++++------------- src/test/ui/consts/issue-64059.rs | 5 +++++ 4 files changed, 13 insertions(+), 27 deletions(-) create mode 100644 src/test/ui/consts/issue-64059.rs diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index f261fdc268b5b..00118c05c9451 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -6,7 +6,7 @@ use std::cell::Cell; use rustc::hir::def::DefKind; use rustc::mir::{ AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue, - Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind, + Local, NullOp, StatementKind, Statement, LocalKind, Static, StaticKind, TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem, SourceScope, SourceScopeLocalData, LocalDecl, }; @@ -407,18 +407,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { let arg = self.eval_operand(arg, source_info)?; let val = self.use_ecx(source_info, |this| { let prim = this.ecx.read_immediate(arg)?; - match op { - UnOp::Neg => { - // Need to do overflow check here: For actual CTFE, MIR - // generation emits code that does this before calling the op. - if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { - throw_panic!(OverflowNeg) - } - } - UnOp::Not => { - // Cannot overflow - } - } // Now run the actual operation. this.ecx.unary_op(op, prim) })?; diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs index a5f685a159b39..5aab1972a9bd5 100644 --- a/src/test/ui/consts/const-err2.rs +++ b/src/test/ui/consts/const-err2.rs @@ -13,7 +13,6 @@ fn black_box(_: T) { fn main() { let a = -std::i8::MIN; - //~^ ERROR const_err let b = 200u8 + 200u8 + 200u8; //~^ ERROR const_err let c = 200u8 * 4; diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr index 659c3afc618a9..63d037764a13d 100644 --- a/src/test/ui/consts/const-err2.stderr +++ b/src/test/ui/consts/const-err2.stderr @@ -1,8 +1,8 @@ error: this expression will panic at runtime - --> $DIR/const-err2.rs:15:13 + --> $DIR/const-err2.rs:16:13 | -LL | let a = -std::i8::MIN; - | ^^^^^^^^^^^^^ attempt to negate with overflow +LL | let b = 200u8 + 200u8 + 200u8; + | ^^^^^^^^^^^^^ attempt to add with overflow | note: lint level defined here --> $DIR/const-err2.rs:8:9 @@ -11,28 +11,22 @@ LL | #![deny(const_err)] | ^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/const-err2.rs:17:13 - | -LL | let b = 200u8 + 200u8 + 200u8; - | ^^^^^^^^^^^^^ attempt to add with overflow - -error: this expression will panic at runtime - --> $DIR/const-err2.rs:19:13 + --> $DIR/const-err2.rs:18:13 | LL | let c = 200u8 * 4; | ^^^^^^^^^ attempt to multiply with overflow error: this expression will panic at runtime - --> $DIR/const-err2.rs:21:13 + --> $DIR/const-err2.rs:20:13 | LL | let d = 42u8 - (42u8 + 1); | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow error: index out of bounds: the len is 1 but the index is 1 - --> $DIR/const-err2.rs:23:14 + --> $DIR/const-err2.rs:22:14 | LL | let _e = [5u8][1]; | ^^^^^^^^ -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs new file mode 100644 index 0000000000000..c4c895fef66cf --- /dev/null +++ b/src/test/ui/consts/issue-64059.rs @@ -0,0 +1,5 @@ +// run-pass + +fn main() { + let _ = -(-0.0); +} From 3a6aadaa8c915c3dea42c0b1fb6d96f227166148 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 2 Sep 2019 01:05:38 +0900 Subject: [PATCH 06/14] Add `opt-level` check --- src/librustc_mir/transform/const_prop.rs | 16 ++- src/test/ui/consts/const-err2.rs | 3 - src/test/ui/consts/const-err2.stderr | 28 +--- .../ui/consts/const-eval/promoted_errors.rs | 1 - .../consts/const-eval/promoted_errors.stderr | 30 ++--- ...t-method-self-inherit-builtin-trait.stderr | 6 + src/test/ui/issues/issue-8460-const.rs | 10 -- src/test/ui/issues/issue-8460-const.stderr | 120 +++++------------- 8 files changed, 67 insertions(+), 147 deletions(-) create mode 100644 src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 00118c05c9451..37e14004ce841 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -6,7 +6,7 @@ use std::cell::Cell; use rustc::hir::def::DefKind; use rustc::mir::{ AggregateKind, Constant, Location, Place, PlaceBase, Body, Operand, Rvalue, - Local, NullOp, StatementKind, Statement, LocalKind, Static, StaticKind, + Local, NullOp, UnOp, StatementKind, Statement, LocalKind, Static, StaticKind, TerminatorKind, Terminator, ClearCrossCrate, SourceInfo, BinOp, ProjectionElem, SourceScope, SourceScopeLocalData, LocalDecl, }; @@ -405,8 +405,20 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } let arg = self.eval_operand(arg, source_info)?; + let is_release_mode = self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2; let val = self.use_ecx(source_info, |this| { let prim = this.ecx.read_immediate(arg)?; + match op { + UnOp::Neg => { + if is_release_mode + && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { + throw_panic!(OverflowNeg) + } + } + UnOp::Not => { + // Cannot overflow + } + } // Now run the actual operation. this.ecx.unary_op(op, prim) })?; @@ -473,7 +485,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Scalar::from_bool(overflow).into(), ) } else { - if overflow { + if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 && overflow { let err = err_panic!(Overflow(op)).into(); let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs index 5aab1972a9bd5..6da6addf60a1c 100644 --- a/src/test/ui/consts/const-err2.rs +++ b/src/test/ui/consts/const-err2.rs @@ -14,11 +14,8 @@ fn black_box(_: T) { fn main() { let a = -std::i8::MIN; let b = 200u8 + 200u8 + 200u8; - //~^ ERROR const_err let c = 200u8 * 4; - //~^ ERROR const_err let d = 42u8 - (42u8 + 1); - //~^ ERROR const_err let _e = [5u8][1]; //~^ ERROR const_err black_box(a); diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr index 63d037764a13d..30855fd215ff3 100644 --- a/src/test/ui/consts/const-err2.stderr +++ b/src/test/ui/consts/const-err2.stderr @@ -1,8 +1,8 @@ -error: this expression will panic at runtime - --> $DIR/const-err2.rs:16:13 +error: index out of bounds: the len is 1 but the index is 1 + --> $DIR/const-err2.rs:19:14 | -LL | let b = 200u8 + 200u8 + 200u8; - | ^^^^^^^^^^^^^ attempt to add with overflow +LL | let _e = [5u8][1]; + | ^^^^^^^^ | note: lint level defined here --> $DIR/const-err2.rs:8:9 @@ -10,23 +10,5 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/const-err2.rs:18:13 - | -LL | let c = 200u8 * 4; - | ^^^^^^^^^ attempt to multiply with overflow - -error: this expression will panic at runtime - --> $DIR/const-err2.rs:20:13 - | -LL | let d = 42u8 - (42u8 + 1); - | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow - -error: index out of bounds: the len is 1 but the index is 1 - --> $DIR/const-err2.rs:22:14 - | -LL | let _e = [5u8][1]; - | ^^^^^^^^ - -error: aborting due to 4 previous errors +error: aborting due to previous error diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index cd989731452b3..a9a7a66fe614f 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -5,7 +5,6 @@ fn main() { println!("{}", 0u32 - 1); let _x = 0u32 - 1; - //~^ ERROR this expression will panic at runtime [const_err] println!("{}", 1/(1-1)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR reaching this expression at runtime will panic or abort [const_err] diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index 40d5c73e86679..3940fa13d7892 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -1,8 +1,8 @@ -error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:7:14 +error: attempt to divide by zero + --> $DIR/promoted_errors.rs:8:20 | -LL | let _x = 0u32 - 1; - | ^^^^^^^^ attempt to subtract with overflow +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ | note: lint level defined here --> $DIR/promoted_errors.rs:3:9 @@ -10,53 +10,47 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ -error: attempt to divide by zero - --> $DIR/promoted_errors.rs:9:20 - | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ - error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:9:20 + --> $DIR/promoted_errors.rs:8:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:12:14 + --> $DIR/promoted_errors.rs:11:14 | LL | let _x = 1/(1-1); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:12:14 + --> $DIR/promoted_errors.rs:11:14 | LL | let _x = 1/(1-1); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:15:20 + --> $DIR/promoted_errors.rs:14:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:15:20 + --> $DIR/promoted_errors.rs:14:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:18:14 + --> $DIR/promoted_errors.rs:17:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:18:14 + --> $DIR/promoted_errors.rs:17:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ attempt to divide by zero -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr new file mode 100644 index 0000000000000..5160c9e72a9c4 --- /dev/null +++ b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr @@ -0,0 +1,6 @@ +error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.0.rcgu.o: 指定されたパスが見つかりません。 (os error 3) + +error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.1.rcgu.o: 指定されたパスが見つかりません。 (os error 3) + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs index 611d280f774c0..6a5b98fa9b190 100644 --- a/src/test/ui/issues/issue-8460-const.rs +++ b/src/test/ui/issues/issue-8460-const.rs @@ -6,19 +6,14 @@ use std::thread; fn main() { assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero //~| ERROR this expression will panic at runtime @@ -36,19 +31,14 @@ fn main() { //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero //~| ERROR this expression will panic at runtime diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr index 31b1da4f804ab..b9fbf0bdaa609 100644 --- a/src/test/ui/issues/issue-8460-const.stderr +++ b/src/test/ui/issues/issue-8460-const.stderr @@ -10,239 +10,179 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:7:36 - | -LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:10:36 + --> $DIR/issue-8460-const.rs:9:36 | LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:10:36 - | -LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:13:36 + --> $DIR/issue-8460-const.rs:11:36 | LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:13:36 - | -LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:16:36 + --> $DIR/issue-8460-const.rs:13:36 | LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:16:36 - | -LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:19:36 + --> $DIR/issue-8460-const.rs:15:36 | LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:19:36 - | -LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:22:36 + --> $DIR/issue-8460-const.rs:17:36 | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:22:36 + --> $DIR/issue-8460-const.rs:17:36 | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:25:36 + --> $DIR/issue-8460-const.rs:20:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:25:36 + --> $DIR/issue-8460-const.rs:20:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:28:36 + --> $DIR/issue-8460-const.rs:23:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:28:36 + --> $DIR/issue-8460-const.rs:23:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:31:36 + --> $DIR/issue-8460-const.rs:26:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:31:36 + --> $DIR/issue-8460-const.rs:26:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:34:36 + --> $DIR/issue-8460-const.rs:29:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:34:36 + --> $DIR/issue-8460-const.rs:29:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:37:36 + --> $DIR/issue-8460-const.rs:32:36 | LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:37:36 - | -LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:40:36 + --> $DIR/issue-8460-const.rs:34:36 | LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:40:36 - | -LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:43:36 + --> $DIR/issue-8460-const.rs:36:36 | LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:43:36 - | -LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:46:36 + --> $DIR/issue-8460-const.rs:38:36 | LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:46:36 - | -LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:49:36 + --> $DIR/issue-8460-const.rs:40:36 | LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:49:36 - | -LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:52:36 + --> $DIR/issue-8460-const.rs:42:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:52:36 + --> $DIR/issue-8460-const.rs:42:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:55:36 + --> $DIR/issue-8460-const.rs:45:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:55:36 + --> $DIR/issue-8460-const.rs:45:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:58:36 + --> $DIR/issue-8460-const.rs:48:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:58:36 + --> $DIR/issue-8460-const.rs:48:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:61:36 + --> $DIR/issue-8460-const.rs:51:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:61:36 + --> $DIR/issue-8460-const.rs:51:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:64:36 + --> $DIR/issue-8460-const.rs:54:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:64:36 + --> $DIR/issue-8460-const.rs:54:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero -error: aborting due to 40 previous errors +error: aborting due to 30 previous errors From ab12dfeb164fb06d19ce24acd8268eebfd6440fa Mon Sep 17 00:00:00 2001 From: Guanqun Lu Date: Mon, 2 Sep 2019 00:38:05 +0800 Subject: [PATCH 07/14] following the same style --- src/tools/compiletest/src/main.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index bde49ff391c8c..467b7771c152e 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -335,7 +335,7 @@ pub fn parse_config(args: Vec) -> Config { runtool: matches.opt_str("runtool"), host_rustcflags: matches.opt_str("host-rustcflags"), target_rustcflags: matches.opt_str("target-rustcflags"), - target: target, + target, host: opt_str2(matches.opt_str("host")), cdb, gdb, @@ -345,7 +345,7 @@ pub fn parse_config(args: Vec) -> Config { lldb_native_rust, llvm_version: matches.opt_str("llvm-version"), system_llvm: matches.opt_present("system-llvm"), - android_cross_path: android_cross_path, + android_cross_path, adb_path: opt_str2(matches.opt_str("adb-path")), adb_test_dir: opt_str2(matches.opt_str("adb-test-dir")), adb_device_status: opt_str2(matches.opt_str("target")).contains("android") From 4a0872b37efbd982aed7e29f166e4ccb095f5779 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 2 Sep 2019 02:18:16 +0900 Subject: [PATCH 08/14] Add `overflow_check` check --- src/librustc_mir/transform/const_prop.rs | 8 ++++++-- ...-8171-default-method-self-inherit-builtin-trait.stderr | 6 ------ 2 files changed, 6 insertions(+), 8 deletions(-) delete mode 100644 src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 37e14004ce841..b43323687cda3 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -405,11 +405,13 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } let arg = self.eval_operand(arg, source_info)?; - let is_release_mode = self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2; + let is_release_mode = self.tcx.sess.overflow_checks(); let val = self.use_ecx(source_info, |this| { let prim = this.ecx.read_immediate(arg)?; match op { UnOp::Neg => { + // We don't have to check overflow here when we already + // check it in release mode. if is_release_mode && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { throw_panic!(OverflowNeg) @@ -485,7 +487,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Scalar::from_bool(overflow).into(), ) } else { - if self.tcx.sess.opts.debugging_opts.mir_opt_level >= 2 && overflow { + // We don't have to check overflow here when we already + // check it in release mode. + if self.tcx.sess.overflow_checks() && overflow { let err = err_panic!(Overflow(op)).into(); let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; diff --git a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr b/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr deleted file mode 100644 index 5160c9e72a9c4..0000000000000 --- a/src/test/ui/issues/issue-8171-default-method-self-inherit-builtin-trait.stderr +++ /dev/null @@ -1,6 +0,0 @@ -error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.0.rcgu.o: 指定されたパスが見つかりません。 (os error 3) - -error: failed to remove $TEST_BUILD_DIR/issues/issue-8171-default-method-self-inherit-builtin-trait/issue-8171-default-method-self-inherit-builtin-trait.issue_8171_default_method_self_inherit_builtin_trait.7rcbfp3g-cgu.1.rcgu.o: 指定されたパスが見つかりません。 (os error 3) - -error: aborting due to 2 previous errors - From f53c2179ba2ae35bd241a28027fb703aec89139b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 1 Sep 2019 10:49:07 -0700 Subject: [PATCH 09/14] review comments --- src/librustc_typeck/check/_match.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 63d059bdf2a80..7427ae9ce8de3 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -117,14 +117,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { &arms[0].body, &mut coercion, ) { - tcx.types.err + tcx.types.err } else { // Only call this if this is not an `if` expr with an expected type and no `else` // clause to avoid duplicated type errors. (#60254) - let arm_ty = self.check_expr_with_expectation(&arm.body, expected); - all_arms_diverge &= self.diverges.get(); - arm_ty + self.check_expr_with_expectation(&arm.body, expected) }; + all_arms_diverge &= self.diverges.get(); if source_if { let then_expr = &arms[0].body; match (i, if_no_else) { @@ -188,6 +187,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } /// Handle the fallback arm of a desugared if(-let) like a missing else. + /// + /// Returns `true` if there was an error forcing the coercion to the `()` type. fn if_fallback_coercion( &self, span: Span, From 8e9825aeb9bce905ed230733bf2a5b4b07f25eb9 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 2 Sep 2019 03:06:11 +0900 Subject: [PATCH 10/14] Fix overflow_check --- src/librustc_mir/transform/const_prop.rs | 14 +- src/test/ui/consts/const-err2.rs | 4 + src/test/ui/consts/const-err2.stderr | 34 ++++- .../ui/consts/const-eval/promoted_errors.rs | 1 + .../consts/const-eval/promoted_errors.stderr | 30 +++-- src/test/ui/consts/issue-64059.rs | 3 +- src/test/ui/consts/issue-64059.stderr | 10 ++ src/test/ui/issues/issue-8460-const.rs | 10 ++ src/test/ui/issues/issue-8460-const.stderr | 120 +++++++++++++----- 9 files changed, 170 insertions(+), 56 deletions(-) create mode 100644 src/test/ui/consts/issue-64059.stderr diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index b43323687cda3..091e68cd0669c 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -405,14 +405,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { } let arg = self.eval_operand(arg, source_info)?; - let is_release_mode = self.tcx.sess.overflow_checks(); + let oflo_check = self.tcx.sess.overflow_checks(); let val = self.use_ecx(source_info, |this| { let prim = this.ecx.read_immediate(arg)?; match op { UnOp::Neg => { - // We don't have to check overflow here when we already - // check it in release mode. - if is_release_mode + // We check overflow in debug mode already + // so should only check in release mode. + if !oflo_check && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { throw_panic!(OverflowNeg) } @@ -487,9 +487,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { Scalar::from_bool(overflow).into(), ) } else { - // We don't have to check overflow here when we already - // check it in release mode. - if self.tcx.sess.overflow_checks() && overflow { + // We check overflow in debug mode already + // so should only check in release mode. + if !self.tcx.sess.overflow_checks() && overflow { let err = err_panic!(Overflow(op)).into(); let _: Option<()> = self.use_ecx(source_info, |_| Err(err)); return None; diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs index 6da6addf60a1c..a5f685a159b39 100644 --- a/src/test/ui/consts/const-err2.rs +++ b/src/test/ui/consts/const-err2.rs @@ -13,9 +13,13 @@ fn black_box(_: T) { fn main() { let a = -std::i8::MIN; + //~^ ERROR const_err let b = 200u8 + 200u8 + 200u8; + //~^ ERROR const_err let c = 200u8 * 4; + //~^ ERROR const_err let d = 42u8 - (42u8 + 1); + //~^ ERROR const_err let _e = [5u8][1]; //~^ ERROR const_err black_box(a); diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr index 30855fd215ff3..659c3afc618a9 100644 --- a/src/test/ui/consts/const-err2.stderr +++ b/src/test/ui/consts/const-err2.stderr @@ -1,8 +1,8 @@ -error: index out of bounds: the len is 1 but the index is 1 - --> $DIR/const-err2.rs:19:14 +error: this expression will panic at runtime + --> $DIR/const-err2.rs:15:13 | -LL | let _e = [5u8][1]; - | ^^^^^^^^ +LL | let a = -std::i8::MIN; + | ^^^^^^^^^^^^^ attempt to negate with overflow | note: lint level defined here --> $DIR/const-err2.rs:8:9 @@ -10,5 +10,29 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ -error: aborting due to previous error +error: this expression will panic at runtime + --> $DIR/const-err2.rs:17:13 + | +LL | let b = 200u8 + 200u8 + 200u8; + | ^^^^^^^^^^^^^ attempt to add with overflow + +error: this expression will panic at runtime + --> $DIR/const-err2.rs:19:13 + | +LL | let c = 200u8 * 4; + | ^^^^^^^^^ attempt to multiply with overflow + +error: this expression will panic at runtime + --> $DIR/const-err2.rs:21:13 + | +LL | let d = 42u8 - (42u8 + 1); + | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + +error: index out of bounds: the len is 1 but the index is 1 + --> $DIR/const-err2.rs:23:14 + | +LL | let _e = [5u8][1]; + | ^^^^^^^^ + +error: aborting due to 5 previous errors diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index a9a7a66fe614f..cd989731452b3 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -5,6 +5,7 @@ fn main() { println!("{}", 0u32 - 1); let _x = 0u32 - 1; + //~^ ERROR this expression will panic at runtime [const_err] println!("{}", 1/(1-1)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR reaching this expression at runtime will panic or abort [const_err] diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index 3940fa13d7892..40d5c73e86679 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -1,8 +1,8 @@ -error: attempt to divide by zero - --> $DIR/promoted_errors.rs:8:20 +error: this expression will panic at runtime + --> $DIR/promoted_errors.rs:7:14 | -LL | println!("{}", 1/(1-1)); - | ^^^^^^^ +LL | let _x = 0u32 - 1; + | ^^^^^^^^ attempt to subtract with overflow | note: lint level defined here --> $DIR/promoted_errors.rs:3:9 @@ -10,47 +10,53 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ +error: attempt to divide by zero + --> $DIR/promoted_errors.rs:9:20 + | +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ + error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:8:20 + --> $DIR/promoted_errors.rs:9:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:11:14 + --> $DIR/promoted_errors.rs:12:14 | LL | let _x = 1/(1-1); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:11:14 + --> $DIR/promoted_errors.rs:12:14 | LL | let _x = 1/(1-1); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:14:20 + --> $DIR/promoted_errors.rs:15:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:14:20 + --> $DIR/promoted_errors.rs:15:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:17:14 + --> $DIR/promoted_errors.rs:18:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:17:14 + --> $DIR/promoted_errors.rs:18:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ attempt to divide by zero -error: aborting due to 8 previous errors +error: aborting due to 9 previous errors diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs index c4c895fef66cf..30b8744cb7fa7 100644 --- a/src/test/ui/consts/issue-64059.rs +++ b/src/test/ui/consts/issue-64059.rs @@ -1,5 +1,4 @@ -// run-pass - fn main() { let _ = -(-0.0); + //~^ ERROR: this expression will panic at runtime } diff --git a/src/test/ui/consts/issue-64059.stderr b/src/test/ui/consts/issue-64059.stderr new file mode 100644 index 0000000000000..6f27653421bd6 --- /dev/null +++ b/src/test/ui/consts/issue-64059.stderr @@ -0,0 +1,10 @@ +error: this expression will panic at runtime + --> $DIR/issue-64059.rs:2:13 + | +LL | let _ = -(-0.0); + | ^^^^^^^ attempt to negate with overflow + | + = note: `#[deny(const_err)]` on by default + +error: aborting due to previous error + diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs index 6a5b98fa9b190..611d280f774c0 100644 --- a/src/test/ui/issues/issue-8460-const.rs +++ b/src/test/ui/issues/issue-8460-const.rs @@ -6,14 +6,19 @@ use std::thread; fn main() { assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero //~| ERROR this expression will panic at runtime @@ -31,14 +36,19 @@ fn main() { //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero //~| ERROR this expression will panic at runtime diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr index b9fbf0bdaa609..31b1da4f804ab 100644 --- a/src/test/ui/issues/issue-8460-const.stderr +++ b/src/test/ui/issues/issue-8460-const.stderr @@ -10,179 +10,239 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:7:36 + | +LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:9:36 + --> $DIR/issue-8460-const.rs:10:36 | LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:10:36 + | +LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:11:36 + --> $DIR/issue-8460-const.rs:13:36 | LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: attempt to divide with overflow +error: this expression will panic at runtime --> $DIR/issue-8460-const.rs:13:36 | +LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to divide with overflow + +error: attempt to divide with overflow + --> $DIR/issue-8460-const.rs:16:36 + | LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:16:36 + | +LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:15:36 + --> $DIR/issue-8460-const.rs:19:36 | LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:19:36 + | +LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:17:36 + --> $DIR/issue-8460-const.rs:22:36 | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:17:36 + --> $DIR/issue-8460-const.rs:22:36 | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:20:36 + --> $DIR/issue-8460-const.rs:25:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:20:36 + --> $DIR/issue-8460-const.rs:25:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:23:36 + --> $DIR/issue-8460-const.rs:28:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:23:36 + --> $DIR/issue-8460-const.rs:28:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:26:36 + --> $DIR/issue-8460-const.rs:31:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:26:36 + --> $DIR/issue-8460-const.rs:31:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:29:36 + --> $DIR/issue-8460-const.rs:34:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:29:36 + --> $DIR/issue-8460-const.rs:34:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:32:36 + --> $DIR/issue-8460-const.rs:37:36 | LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:37:36 + | +LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:34:36 + --> $DIR/issue-8460-const.rs:40:36 | LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:40:36 + | +LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:36:36 + --> $DIR/issue-8460-const.rs:43:36 | LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:43:36 + | +LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:38:36 + --> $DIR/issue-8460-const.rs:46:36 | LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:46:36 + | +LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:40:36 + --> $DIR/issue-8460-const.rs:49:36 | LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:49:36 + | +LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:42:36 + --> $DIR/issue-8460-const.rs:52:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:42:36 + --> $DIR/issue-8460-const.rs:52:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:45:36 + --> $DIR/issue-8460-const.rs:55:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:45:36 + --> $DIR/issue-8460-const.rs:55:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:48:36 + --> $DIR/issue-8460-const.rs:58:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:48:36 + --> $DIR/issue-8460-const.rs:58:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:51:36 + --> $DIR/issue-8460-const.rs:61:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:51:36 + --> $DIR/issue-8460-const.rs:61:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:54:36 + --> $DIR/issue-8460-const.rs:64:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:54:36 + --> $DIR/issue-8460-const.rs:64:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero -error: aborting due to 30 previous errors +error: aborting due to 40 previous errors From 141f5a7558289acb6c7aaf9c6500eb9f6dbeec1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Sun, 1 Sep 2019 11:20:33 -0700 Subject: [PATCH 11/14] review comments --- src/librustc/ty/context.rs | 16 +----- src/librustc_typeck/check/expr.rs | 94 ++++++++++++++++++------------- 2 files changed, 57 insertions(+), 53 deletions(-) diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index f355e231914d2..17c9e520bcea2 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -2403,20 +2403,8 @@ impl<'tcx> TyCtxt<'tcx> { } #[inline] - pub fn mk_pin(self, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = self.require_lang_item(lang_items::PinTypeLangItem, None); - self.mk_generic_adt(def_id, ty) - } - - #[inline] - pub fn mk_rc(self, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = self.require_lang_item(lang_items::Rc, None); - self.mk_generic_adt(def_id, ty) - } - - #[inline] - pub fn mk_arc(self, ty: Ty<'tcx>) -> Ty<'tcx> { - let def_id = self.require_lang_item(lang_items::Arc, None); + pub fn mk_lang_item(self, ty: Ty<'tcx>, item: lang_items::LangItem) -> Ty<'tcx> { + let def_id = self.require_lang_item(item, None); self.mk_generic_adt(def_id, ty) } diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs index efff8bcdacbcf..fbaa9904d8303 100644 --- a/src/librustc_typeck/check/expr.rs +++ b/src/librustc_typeck/check/expr.rs @@ -12,7 +12,7 @@ use crate::check::fatally_break_rust; use crate::check::report_unexpected_variant_res; use crate::check::Needs; use crate::check::TupleArgumentsFlag::DontTupleArguments; -use crate::check::method::{probe, SelfSource}; +use crate::check::method::{probe, SelfSource, MethodError}; use crate::util::common::ErrorReported; use crate::util::nodemap::FxHashMap; use crate::astconv::AstConv as _; @@ -29,6 +29,7 @@ use rustc::hir::def::{CtorKind, Res, DefKind}; use rustc::hir::ptr::P; use rustc::infer; use rustc::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; +use rustc::middle::lang_items; use rustc::mir::interpret::GlobalId; use rustc::ty; use rustc::ty::adjustment::{ @@ -775,21 +776,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // no need to check for bot/err -- callee does that let rcvr_t = self.structurally_resolved_type(args[0].span, rcvr_t); - let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| { - if let Ok(pick) = self.lookup_probe( - span, - segment.ident, - new_rcvr_t, - rcvr, - probe::ProbeScope::AllTraits, - ) { - err.span_label( - pick.item.ident.span, - &format!("the method is available for `{}` here", new_rcvr_t), - ); - } - }; - let method = match self.lookup_method(rcvr_t, segment, span, expr, rcvr) { Ok(method) => { self.write_method_call(expr.hir_id, method); @@ -797,29 +783,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } Err(error) => { if segment.ident.name != kw::Invalid { - if let Some(mut err) = self.report_method_error( - span, - rcvr_t, - segment.ident, - SelfSource::MethodCall(rcvr), - error, - Some(args), - ) { - if let ty::Adt(..) = rcvr_t.sty { - // Try alternative arbitrary self types that could fulfill this call. - // FIXME: probe for all types that *could* be arbitrary self-types, not - // just this whitelist. - let box_rcvr_t = self.tcx.mk_box(rcvr_t); - try_alt_rcvr(&mut err, box_rcvr_t); - let pin_rcvr_t = self.tcx.mk_pin(rcvr_t); - try_alt_rcvr(&mut err, pin_rcvr_t); - let arc_rcvr_t = self.tcx.mk_arc(rcvr_t); - try_alt_rcvr(&mut err, arc_rcvr_t); - let rc_rcvr_t = self.tcx.mk_rc(rcvr_t); - try_alt_rcvr(&mut err, rc_rcvr_t); - } - err.emit(); - } + self.report_extended_method_error(segment, span, args, rcvr_t, error); } Err(()) } @@ -836,6 +800,58 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { ) } + fn report_extended_method_error( + &self, + segment: &hir::PathSegment, + span: Span, + args: &'tcx [hir::Expr], + rcvr_t: Ty<'tcx>, + error: MethodError<'tcx> + ) { + let rcvr = &args[0]; + let try_alt_rcvr = |err: &mut DiagnosticBuilder<'_>, new_rcvr_t| { + if let Ok(pick) = self.lookup_probe( + span, + segment.ident, + new_rcvr_t, + rcvr, + probe::ProbeScope::AllTraits, + ) { + err.span_label( + pick.item.ident.span, + &format!("the method is available for `{}` here", new_rcvr_t), + ); + } + }; + + if let Some(mut err) = self.report_method_error( + span, + rcvr_t, + segment.ident, + SelfSource::MethodCall(rcvr), + error, + Some(args), + ) { + if let ty::Adt(..) = rcvr_t.sty { + // Try alternative arbitrary self types that could fulfill this call. + // FIXME: probe for all types that *could* be arbitrary self-types, not + // just this whitelist. + let box_rcvr_t = self.tcx.mk_box(rcvr_t); + try_alt_rcvr(&mut err, box_rcvr_t); + let pin_rcvr_t = self.tcx.mk_lang_item( + rcvr_t, + lang_items::PinTypeLangItem, + ); + try_alt_rcvr(&mut err, pin_rcvr_t); + let arc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Arc); + try_alt_rcvr(&mut err, arc_rcvr_t); + let rc_rcvr_t = self.tcx.mk_lang_item(rcvr_t, lang_items::Rc); + try_alt_rcvr(&mut err, rc_rcvr_t); + } + err.emit(); + } + } + fn check_expr_cast( &self, e: &'tcx hir::Expr, From 0cd9c1623fb5858990892fed2fbf7c06e7b25f22 Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 2 Sep 2019 03:40:35 +0900 Subject: [PATCH 12/14] Fix condition and tests' flags --- src/librustc_mir/transform/const_prop.rs | 1 + src/test/ui/consts/const-err2.rs | 2 + src/test/ui/consts/const-err2.stderr | 28 ++-- .../ui/consts/const-eval/promoted_errors.rs | 5 +- .../consts/const-eval/promoted_errors.stderr | 32 +++-- src/test/ui/consts/issue-64059.rs | 4 +- src/test/ui/consts/issue-64059.stderr | 10 -- src/test/ui/issues/issue-8460-const.rs | 12 +- src/test/ui/issues/issue-8460-const.stderr | 122 +++++------------- 9 files changed, 75 insertions(+), 141 deletions(-) delete mode 100644 src/test/ui/consts/issue-64059.stderr diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs index 091e68cd0669c..e4b186736e2a1 100644 --- a/src/librustc_mir/transform/const_prop.rs +++ b/src/librustc_mir/transform/const_prop.rs @@ -413,6 +413,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { // We check overflow in debug mode already // so should only check in release mode. if !oflo_check + && prim.layout.ty.is_signed() && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) { throw_panic!(OverflowNeg) } diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs index a5f685a159b39..cd6ac47bd92a8 100644 --- a/src/test/ui/consts/const-err2.rs +++ b/src/test/ui/consts/const-err2.rs @@ -5,6 +5,8 @@ #![feature(rustc_attrs)] #![allow(exceeding_bitshifts)] +// compile-flags: -C overflow-checks=on -O + #![deny(const_err)] fn black_box(_: T) { diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr index 659c3afc618a9..ecfced7f0db8b 100644 --- a/src/test/ui/consts/const-err2.stderr +++ b/src/test/ui/consts/const-err2.stderr @@ -1,35 +1,35 @@ -error: this expression will panic at runtime - --> $DIR/const-err2.rs:15:13 +error: attempt to negate with overflow + --> $DIR/const-err2.rs:17:13 | LL | let a = -std::i8::MIN; - | ^^^^^^^^^^^^^ attempt to negate with overflow + | ^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/const-err2.rs:8:9 + --> $DIR/const-err2.rs:10:9 | LL | #![deny(const_err)] | ^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/const-err2.rs:17:13 +error: attempt to add with overflow + --> $DIR/const-err2.rs:19:13 | LL | let b = 200u8 + 200u8 + 200u8; - | ^^^^^^^^^^^^^ attempt to add with overflow + | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/const-err2.rs:19:13 +error: attempt to multiply with overflow + --> $DIR/const-err2.rs:21:13 | LL | let c = 200u8 * 4; - | ^^^^^^^^^ attempt to multiply with overflow + | ^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/const-err2.rs:21:13 +error: attempt to subtract with overflow + --> $DIR/const-err2.rs:23:13 | LL | let d = 42u8 - (42u8 + 1); - | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow + | ^^^^^^^^^^^^^^^^^ error: index out of bounds: the len is 1 but the index is 1 - --> $DIR/const-err2.rs:23:14 + --> $DIR/const-err2.rs:25:14 | LL | let _e = [5u8][1]; | ^^^^^^^^ diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index cd989731452b3..7adb394144bdd 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -1,11 +1,12 @@ -// compile-flags: -O +// compile-flags: -C overflow-checks=on -O #![deny(const_err)] fn main() { println!("{}", 0u32 - 1); + //~^ ERROR attempt to subtract with overflow let _x = 0u32 - 1; - //~^ ERROR this expression will panic at runtime [const_err] + //~^ ERROR attempt to subtract with overflow println!("{}", 1/(1-1)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR reaching this expression at runtime will panic or abort [const_err] diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index 40d5c73e86679..fe63d0800dd7c 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -1,8 +1,8 @@ -error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:7:14 +error: attempt to subtract with overflow + --> $DIR/promoted_errors.rs:6:20 | -LL | let _x = 0u32 - 1; - | ^^^^^^^^ attempt to subtract with overflow +LL | println!("{}", 0u32 - 1); + | ^^^^^^^^ | note: lint level defined here --> $DIR/promoted_errors.rs:3:9 @@ -10,53 +10,59 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ +error: attempt to subtract with overflow + --> $DIR/promoted_errors.rs:8:14 + | +LL | let _x = 0u32 - 1; + | ^^^^^^^^ + error: attempt to divide by zero - --> $DIR/promoted_errors.rs:9:20 + --> $DIR/promoted_errors.rs:10:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:9:20 + --> $DIR/promoted_errors.rs:10:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:12:14 + --> $DIR/promoted_errors.rs:13:14 | LL | let _x = 1/(1-1); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:12:14 + --> $DIR/promoted_errors.rs:13:14 | LL | let _x = 1/(1-1); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:15:20 + --> $DIR/promoted_errors.rs:16:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:15:20 + --> $DIR/promoted_errors.rs:16:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:18:14 + --> $DIR/promoted_errors.rs:19:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:18:14 + --> $DIR/promoted_errors.rs:19:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ attempt to divide by zero -error: aborting due to 9 previous errors +error: aborting due to 10 previous errors diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs index 30b8744cb7fa7..38911c3dcf692 100644 --- a/src/test/ui/consts/issue-64059.rs +++ b/src/test/ui/consts/issue-64059.rs @@ -1,4 +1,6 @@ +// compile-flags: -C overflow-checks=on -O +// run-pass + fn main() { let _ = -(-0.0); - //~^ ERROR: this expression will panic at runtime } diff --git a/src/test/ui/consts/issue-64059.stderr b/src/test/ui/consts/issue-64059.stderr deleted file mode 100644 index 6f27653421bd6..0000000000000 --- a/src/test/ui/consts/issue-64059.stderr +++ /dev/null @@ -1,10 +0,0 @@ -error: this expression will panic at runtime - --> $DIR/issue-64059.rs:2:13 - | -LL | let _ = -(-0.0); - | ^^^^^^^ attempt to negate with overflow - | - = note: `#[deny(const_err)]` on by default - -error: aborting due to previous error - diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs index 611d280f774c0..c3f53e3298b2b 100644 --- a/src/test/ui/issues/issue-8460-const.rs +++ b/src/test/ui/issues/issue-8460-const.rs @@ -1,3 +1,5 @@ +// compile-flags: -C overflow-checks=on -O + #![deny(const_err)] use std::{isize, i8, i16, i32, i64}; @@ -6,19 +8,14 @@ use std::thread; fn main() { assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero //~| ERROR this expression will panic at runtime @@ -36,19 +33,14 @@ fn main() { //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow - //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero //~| ERROR this expression will panic at runtime diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr index 31b1da4f804ab..914323227ddd2 100644 --- a/src/test/ui/issues/issue-8460-const.stderr +++ b/src/test/ui/issues/issue-8460-const.stderr @@ -1,248 +1,188 @@ error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:7:36 + --> $DIR/issue-8460-const.rs:9:36 | LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/issue-8460-const.rs:1:9 + --> $DIR/issue-8460-const.rs:3:9 | LL | #![deny(const_err)] | ^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:7:36 - | -LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:10:36 + --> $DIR/issue-8460-const.rs:11:36 | LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:10:36 - | -LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow --> $DIR/issue-8460-const.rs:13:36 | LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:13:36 - | -LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:16:36 + --> $DIR/issue-8460-const.rs:15:36 | LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:16:36 - | -LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:19:36 + --> $DIR/issue-8460-const.rs:17:36 | LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:19:36 - | -LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to divide with overflow - error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:22:36 + --> $DIR/issue-8460-const.rs:19:36 | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:22:36 + --> $DIR/issue-8460-const.rs:19:36 | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:25:36 + --> $DIR/issue-8460-const.rs:22:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:25:36 + --> $DIR/issue-8460-const.rs:22:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:28:36 + --> $DIR/issue-8460-const.rs:25:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:28:36 + --> $DIR/issue-8460-const.rs:25:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:31:36 + --> $DIR/issue-8460-const.rs:28:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:31:36 + --> $DIR/issue-8460-const.rs:28:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:34:36 + --> $DIR/issue-8460-const.rs:31:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:34:36 + --> $DIR/issue-8460-const.rs:31:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:37:36 + --> $DIR/issue-8460-const.rs:34:36 | LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:37:36 - | -LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:40:36 + --> $DIR/issue-8460-const.rs:36:36 | LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:40:36 - | -LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:43:36 + --> $DIR/issue-8460-const.rs:38:36 | LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:43:36 - | -LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:46:36 + --> $DIR/issue-8460-const.rs:40:36 | LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:46:36 - | -LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:49:36 + --> $DIR/issue-8460-const.rs:42:36 | LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:49:36 - | -LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); - | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow - error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:52:36 + --> $DIR/issue-8460-const.rs:44:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:52:36 + --> $DIR/issue-8460-const.rs:44:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:55:36 + --> $DIR/issue-8460-const.rs:47:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:55:36 + --> $DIR/issue-8460-const.rs:47:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:58:36 + --> $DIR/issue-8460-const.rs:50:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:58:36 + --> $DIR/issue-8460-const.rs:50:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:61:36 + --> $DIR/issue-8460-const.rs:53:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:61:36 + --> $DIR/issue-8460-const.rs:53:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:64:36 + --> $DIR/issue-8460-const.rs:56:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:64:36 + --> $DIR/issue-8460-const.rs:56:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero -error: aborting due to 40 previous errors +error: aborting due to 30 previous errors From a937d8cdeb56ed72897ecf14469f89f18814554c Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Mon, 2 Sep 2019 05:01:39 +0900 Subject: [PATCH 13/14] Fix tests again --- src/test/ui/consts/const-err2.rs | 3 +- src/test/ui/consts/const-err2.stderr | 28 +-- src/test/ui/consts/const-err3.rs | 30 +++ src/test/ui/consts/const-err3.stderr | 38 ++++ .../ui/consts/const-eval/promoted_errors.rs | 5 +- .../consts/const-eval/promoted_errors.stderr | 32 ++- .../ui/consts/const-eval/promoted_errors2.rs | 22 ++ .../consts/const-eval/promoted_errors2.stderr | 68 +++++++ src/test/ui/consts/issue-64059-2.rs | 6 + src/test/ui/consts/issue-64059.rs | 1 - src/test/ui/issues/issue-8460-const.rs | 12 +- src/test/ui/issues/issue-8460-const.stderr | 122 +++++++++--- src/test/ui/issues/issue-8460-const2.rs | 59 ++++++ src/test/ui/issues/issue-8460-const2.stderr | 188 ++++++++++++++++++ 14 files changed, 542 insertions(+), 72 deletions(-) create mode 100644 src/test/ui/consts/const-err3.rs create mode 100644 src/test/ui/consts/const-err3.stderr create mode 100644 src/test/ui/consts/const-eval/promoted_errors2.rs create mode 100644 src/test/ui/consts/const-eval/promoted_errors2.stderr create mode 100644 src/test/ui/consts/issue-64059-2.rs create mode 100644 src/test/ui/issues/issue-8460-const2.rs create mode 100644 src/test/ui/issues/issue-8460-const2.stderr diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs index cd6ac47bd92a8..ecbcc2a4b496f 100644 --- a/src/test/ui/consts/const-err2.rs +++ b/src/test/ui/consts/const-err2.rs @@ -5,7 +5,6 @@ #![feature(rustc_attrs)] #![allow(exceeding_bitshifts)] -// compile-flags: -C overflow-checks=on -O #![deny(const_err)] @@ -23,7 +22,7 @@ fn main() { let d = 42u8 - (42u8 + 1); //~^ ERROR const_err let _e = [5u8][1]; - //~^ ERROR const_err + //~^ ERROR index out of bounds black_box(a); black_box(b); black_box(c); diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr index ecfced7f0db8b..1d84d44dc27b3 100644 --- a/src/test/ui/consts/const-err2.stderr +++ b/src/test/ui/consts/const-err2.stderr @@ -1,35 +1,35 @@ -error: attempt to negate with overflow - --> $DIR/const-err2.rs:17:13 +error: this expression will panic at runtime + --> $DIR/const-err2.rs:16:13 | LL | let a = -std::i8::MIN; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ attempt to negate with overflow | note: lint level defined here - --> $DIR/const-err2.rs:10:9 + --> $DIR/const-err2.rs:9:9 | LL | #![deny(const_err)] | ^^^^^^^^^ -error: attempt to add with overflow - --> $DIR/const-err2.rs:19:13 +error: this expression will panic at runtime + --> $DIR/const-err2.rs:18:13 | LL | let b = 200u8 + 200u8 + 200u8; - | ^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^ attempt to add with overflow -error: attempt to multiply with overflow - --> $DIR/const-err2.rs:21:13 +error: this expression will panic at runtime + --> $DIR/const-err2.rs:20:13 | LL | let c = 200u8 * 4; - | ^^^^^^^^^ + | ^^^^^^^^^ attempt to multiply with overflow -error: attempt to subtract with overflow - --> $DIR/const-err2.rs:23:13 +error: this expression will panic at runtime + --> $DIR/const-err2.rs:22:13 | LL | let d = 42u8 - (42u8 + 1); - | ^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow error: index out of bounds: the len is 1 but the index is 1 - --> $DIR/const-err2.rs:25:14 + --> $DIR/const-err2.rs:24:14 | LL | let _e = [5u8][1]; | ^^^^^^^^ diff --git a/src/test/ui/consts/const-err3.rs b/src/test/ui/consts/const-err3.rs new file mode 100644 index 0000000000000..a9cf04cda7a5a --- /dev/null +++ b/src/test/ui/consts/const-err3.rs @@ -0,0 +1,30 @@ +// needed because negating int::MIN will behave differently between +// optimized compilation and unoptimized compilation and thus would +// lead to different lints being emitted +// compile-flags: -C overflow-checks=on -O + +#![feature(rustc_attrs)] +#![allow(exceeding_bitshifts)] + +#![deny(const_err)] + +fn black_box(_: T) { + unimplemented!() +} + +fn main() { + let a = -std::i8::MIN; + //~^ ERROR const_err + let b = 200u8 + 200u8 + 200u8; + //~^ ERROR const_err + let c = 200u8 * 4; + //~^ ERROR const_err + let d = 42u8 - (42u8 + 1); + //~^ ERROR const_err + let _e = [5u8][1]; + //~^ ERROR const_err + black_box(a); + black_box(b); + black_box(c); + black_box(d); +} diff --git a/src/test/ui/consts/const-err3.stderr b/src/test/ui/consts/const-err3.stderr new file mode 100644 index 0000000000000..0602707be7040 --- /dev/null +++ b/src/test/ui/consts/const-err3.stderr @@ -0,0 +1,38 @@ +error: attempt to negate with overflow + --> $DIR/const-err3.rs:16:13 + | +LL | let a = -std::i8::MIN; + | ^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/const-err3.rs:9:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + +error: attempt to add with overflow + --> $DIR/const-err3.rs:18:13 + | +LL | let b = 200u8 + 200u8 + 200u8; + | ^^^^^^^^^^^^^ + +error: attempt to multiply with overflow + --> $DIR/const-err3.rs:20:13 + | +LL | let c = 200u8 * 4; + | ^^^^^^^^^ + +error: attempt to subtract with overflow + --> $DIR/const-err3.rs:22:13 + | +LL | let d = 42u8 - (42u8 + 1); + | ^^^^^^^^^^^^^^^^^ + +error: index out of bounds: the len is 1 but the index is 1 + --> $DIR/const-err3.rs:24:14 + | +LL | let _e = [5u8][1]; + | ^^^^^^^^ + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs index 7adb394144bdd..45941398f4b66 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.rs +++ b/src/test/ui/consts/const-eval/promoted_errors.rs @@ -1,12 +1,11 @@ -// compile-flags: -C overflow-checks=on -O +// compile-flags: -O #![deny(const_err)] fn main() { println!("{}", 0u32 - 1); - //~^ ERROR attempt to subtract with overflow let _x = 0u32 - 1; - //~^ ERROR attempt to subtract with overflow + //~^ ERROR const_err println!("{}", 1/(1-1)); //~^ ERROR attempt to divide by zero [const_err] //~| ERROR reaching this expression at runtime will panic or abort [const_err] diff --git a/src/test/ui/consts/const-eval/promoted_errors.stderr b/src/test/ui/consts/const-eval/promoted_errors.stderr index fe63d0800dd7c..40d5c73e86679 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.stderr @@ -1,8 +1,8 @@ -error: attempt to subtract with overflow - --> $DIR/promoted_errors.rs:6:20 +error: this expression will panic at runtime + --> $DIR/promoted_errors.rs:7:14 | -LL | println!("{}", 0u32 - 1); - | ^^^^^^^^ +LL | let _x = 0u32 - 1; + | ^^^^^^^^ attempt to subtract with overflow | note: lint level defined here --> $DIR/promoted_errors.rs:3:9 @@ -10,59 +10,53 @@ note: lint level defined here LL | #![deny(const_err)] | ^^^^^^^^^ -error: attempt to subtract with overflow - --> $DIR/promoted_errors.rs:8:14 - | -LL | let _x = 0u32 - 1; - | ^^^^^^^^ - error: attempt to divide by zero - --> $DIR/promoted_errors.rs:10:20 + --> $DIR/promoted_errors.rs:9:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:10:20 + --> $DIR/promoted_errors.rs:9:20 | LL | println!("{}", 1/(1-1)); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:13:14 + --> $DIR/promoted_errors.rs:12:14 | LL | let _x = 1/(1-1); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:13:14 + --> $DIR/promoted_errors.rs:12:14 | LL | let _x = 1/(1-1); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:16:20 + --> $DIR/promoted_errors.rs:15:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ error: reaching this expression at runtime will panic or abort - --> $DIR/promoted_errors.rs:16:20 + --> $DIR/promoted_errors.rs:15:20 | LL | println!("{}", 1/(false as u32)); | ^^^^^^^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/promoted_errors.rs:19:14 + --> $DIR/promoted_errors.rs:18:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/promoted_errors.rs:19:14 + --> $DIR/promoted_errors.rs:18:14 | LL | let _x = 1/(false as u32); | ^^^^^^^^^^^^^^^^ attempt to divide by zero -error: aborting due to 10 previous errors +error: aborting due to 9 previous errors diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs new file mode 100644 index 0000000000000..7adb394144bdd --- /dev/null +++ b/src/test/ui/consts/const-eval/promoted_errors2.rs @@ -0,0 +1,22 @@ +// compile-flags: -C overflow-checks=on -O + +#![deny(const_err)] + +fn main() { + println!("{}", 0u32 - 1); + //~^ ERROR attempt to subtract with overflow + let _x = 0u32 - 1; + //~^ ERROR attempt to subtract with overflow + println!("{}", 1/(1-1)); + //~^ ERROR attempt to divide by zero [const_err] + //~| ERROR reaching this expression at runtime will panic or abort [const_err] + let _x = 1/(1-1); + //~^ ERROR const_err + //~| ERROR const_err + println!("{}", 1/(false as u32)); + //~^ ERROR attempt to divide by zero [const_err] + //~| ERROR reaching this expression at runtime will panic or abort [const_err] + let _x = 1/(false as u32); + //~^ ERROR const_err + //~| ERROR const_err +} diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr new file mode 100644 index 0000000000000..2819e6e8fdbe0 --- /dev/null +++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr @@ -0,0 +1,68 @@ +error: attempt to subtract with overflow + --> $DIR/promoted_errors2.rs:6:20 + | +LL | println!("{}", 0u32 - 1); + | ^^^^^^^^ + | +note: lint level defined here + --> $DIR/promoted_errors2.rs:3:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + +error: attempt to subtract with overflow + --> $DIR/promoted_errors2.rs:8:14 + | +LL | let _x = 0u32 - 1; + | ^^^^^^^^ + +error: attempt to divide by zero + --> $DIR/promoted_errors2.rs:10:20 + | +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ + +error: reaching this expression at runtime will panic or abort + --> $DIR/promoted_errors2.rs:10:20 + | +LL | println!("{}", 1/(1-1)); + | ^^^^^^^ attempt to divide by zero + +error: attempt to divide by zero + --> $DIR/promoted_errors2.rs:13:14 + | +LL | let _x = 1/(1-1); + | ^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/promoted_errors2.rs:13:14 + | +LL | let _x = 1/(1-1); + | ^^^^^^^ attempt to divide by zero + +error: attempt to divide by zero + --> $DIR/promoted_errors2.rs:16:20 + | +LL | println!("{}", 1/(false as u32)); + | ^^^^^^^^^^^^^^^^ + +error: reaching this expression at runtime will panic or abort + --> $DIR/promoted_errors2.rs:16:20 + | +LL | println!("{}", 1/(false as u32)); + | ^^^^^^^^^^^^^^^^ attempt to divide by zero + +error: attempt to divide by zero + --> $DIR/promoted_errors2.rs:19:14 + | +LL | let _x = 1/(false as u32); + | ^^^^^^^^^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/promoted_errors2.rs:19:14 + | +LL | let _x = 1/(false as u32); + | ^^^^^^^^^^^^^^^^ attempt to divide by zero + +error: aborting due to 10 previous errors + diff --git a/src/test/ui/consts/issue-64059-2.rs b/src/test/ui/consts/issue-64059-2.rs new file mode 100644 index 0000000000000..38911c3dcf692 --- /dev/null +++ b/src/test/ui/consts/issue-64059-2.rs @@ -0,0 +1,6 @@ +// compile-flags: -C overflow-checks=on -O +// run-pass + +fn main() { + let _ = -(-0.0); +} diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs index 38911c3dcf692..c4c895fef66cf 100644 --- a/src/test/ui/consts/issue-64059.rs +++ b/src/test/ui/consts/issue-64059.rs @@ -1,4 +1,3 @@ -// compile-flags: -C overflow-checks=on -O // run-pass fn main() { diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs index c3f53e3298b2b..611d280f774c0 100644 --- a/src/test/ui/issues/issue-8460-const.rs +++ b/src/test/ui/issues/issue-8460-const.rs @@ -1,5 +1,3 @@ -// compile-flags: -C overflow-checks=on -O - #![deny(const_err)] use std::{isize, i8, i16, i32, i64}; @@ -8,14 +6,19 @@ use std::thread; fn main() { assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); //~^ ERROR attempt to divide with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); //~^ ERROR attempt to divide by zero //~| ERROR this expression will panic at runtime @@ -33,14 +36,19 @@ fn main() { //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with overflow + //~| ERROR this expression will panic at runtime assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); //~^ ERROR attempt to calculate the remainder with a divisor of zero //~| ERROR this expression will panic at runtime diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr index 914323227ddd2..31b1da4f804ab 100644 --- a/src/test/ui/issues/issue-8460-const.stderr +++ b/src/test/ui/issues/issue-8460-const.stderr @@ -1,188 +1,248 @@ error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:9:36 + --> $DIR/issue-8460-const.rs:7:36 | LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ | note: lint level defined here - --> $DIR/issue-8460-const.rs:3:9 + --> $DIR/issue-8460-const.rs:1:9 | LL | #![deny(const_err)] | ^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:7:36 + | +LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:11:36 + --> $DIR/issue-8460-const.rs:10:36 | LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:10:36 + | +LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide with overflow --> $DIR/issue-8460-const.rs:13:36 | LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:13:36 + | +LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:15:36 + --> $DIR/issue-8460-const.rs:16:36 | LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:16:36 + | +LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to divide with overflow + error: attempt to divide with overflow - --> $DIR/issue-8460-const.rs:17:36 + --> $DIR/issue-8460-const.rs:19:36 | LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); | ^^^^^^^^^^^^^ -error: attempt to divide by zero +error: this expression will panic at runtime --> $DIR/issue-8460-const.rs:19:36 | +LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to divide with overflow + +error: attempt to divide by zero + --> $DIR/issue-8460-const.rs:22:36 + | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:19:36 + --> $DIR/issue-8460-const.rs:22:36 | LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); | ^^^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:22:36 + --> $DIR/issue-8460-const.rs:25:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:22:36 + --> $DIR/issue-8460-const.rs:25:36 | LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); | ^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:25:36 + --> $DIR/issue-8460-const.rs:28:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:25:36 + --> $DIR/issue-8460-const.rs:28:36 | LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:28:36 + --> $DIR/issue-8460-const.rs:31:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:28:36 + --> $DIR/issue-8460-const.rs:31:36 | LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to divide by zero - --> $DIR/issue-8460-const.rs:31:36 + --> $DIR/issue-8460-const.rs:34:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:31:36 + --> $DIR/issue-8460-const.rs:34:36 | LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); | ^^^^^^^^ attempt to divide by zero error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:34:36 + --> $DIR/issue-8460-const.rs:37:36 | LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:37:36 + | +LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:36:36 + --> $DIR/issue-8460-const.rs:40:36 | LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:40:36 + | +LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:38:36 + --> $DIR/issue-8460-const.rs:43:36 | LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:43:36 + | +LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:40:36 + --> $DIR/issue-8460-const.rs:46:36 | LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:46:36 + | +LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with overflow - --> $DIR/issue-8460-const.rs:42:36 + --> $DIR/issue-8460-const.rs:49:36 | LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); | ^^^^^^^^^^^^^ +error: this expression will panic at runtime + --> $DIR/issue-8460-const.rs:49:36 + | +LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow + error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:44:36 + --> $DIR/issue-8460-const.rs:52:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:44:36 + --> $DIR/issue-8460-const.rs:52:36 | LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:47:36 + --> $DIR/issue-8460-const.rs:55:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:47:36 + --> $DIR/issue-8460-const.rs:55:36 | LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); | ^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:50:36 + --> $DIR/issue-8460-const.rs:58:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:50:36 + --> $DIR/issue-8460-const.rs:58:36 | LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:53:36 + --> $DIR/issue-8460-const.rs:61:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:53:36 + --> $DIR/issue-8460-const.rs:61:36 | LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero error: attempt to calculate the remainder with a divisor of zero - --> $DIR/issue-8460-const.rs:56:36 + --> $DIR/issue-8460-const.rs:64:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ error: this expression will panic at runtime - --> $DIR/issue-8460-const.rs:56:36 + --> $DIR/issue-8460-const.rs:64:36 | LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero -error: aborting due to 30 previous errors +error: aborting due to 40 previous errors diff --git a/src/test/ui/issues/issue-8460-const2.rs b/src/test/ui/issues/issue-8460-const2.rs new file mode 100644 index 0000000000000..c3f53e3298b2b --- /dev/null +++ b/src/test/ui/issues/issue-8460-const2.rs @@ -0,0 +1,59 @@ +// compile-flags: -C overflow-checks=on -O + +#![deny(const_err)] + +use std::{isize, i8, i16, i32, i64}; +use std::thread; + +fn main() { + assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); + //~^ ERROR attempt to divide with overflow + assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); + //~^ ERROR attempt to divide with overflow + assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); + //~^ ERROR attempt to divide with overflow + assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); + //~^ ERROR attempt to divide with overflow + assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); + //~^ ERROR attempt to divide with overflow + assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); + //~^ ERROR attempt to divide by zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); + //~^ ERROR attempt to divide by zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); + //~^ ERROR attempt to divide by zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); + //~^ ERROR attempt to divide by zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); + //~^ ERROR attempt to divide by zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with overflow + assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with overflow + assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with overflow + assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with overflow + assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with overflow + assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with a divisor of zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with a divisor of zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with a divisor of zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with a divisor of zero + //~| ERROR this expression will panic at runtime + assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); + //~^ ERROR attempt to calculate the remainder with a divisor of zero + //~| ERROR this expression will panic at runtime +} diff --git a/src/test/ui/issues/issue-8460-const2.stderr b/src/test/ui/issues/issue-8460-const2.stderr new file mode 100644 index 0000000000000..b688ec1367794 --- /dev/null +++ b/src/test/ui/issues/issue-8460-const2.stderr @@ -0,0 +1,188 @@ +error: attempt to divide with overflow + --> $DIR/issue-8460-const2.rs:9:36 + | +LL | assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/issue-8460-const2.rs:3:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + +error: attempt to divide with overflow + --> $DIR/issue-8460-const2.rs:11:36 + | +LL | assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^ + +error: attempt to divide with overflow + --> $DIR/issue-8460-const2.rs:13:36 + | +LL | assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ + +error: attempt to divide with overflow + --> $DIR/issue-8460-const2.rs:15:36 + | +LL | assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ + +error: attempt to divide with overflow + --> $DIR/issue-8460-const2.rs:17:36 + | +LL | assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err()); + | ^^^^^^^^^^^^^ + +error: attempt to divide by zero + --> $DIR/issue-8460-const2.rs:19:36 + | +LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); + | ^^^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:19:36 + | +LL | assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err()); + | ^^^^^^^^^^ attempt to divide by zero + +error: attempt to divide by zero + --> $DIR/issue-8460-const2.rs:22:36 + | +LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); + | ^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:22:36 + | +LL | assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err()); + | ^^^^^^^ attempt to divide by zero + +error: attempt to divide by zero + --> $DIR/issue-8460-const2.rs:25:36 + | +LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); + | ^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:25:36 + | +LL | assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err()); + | ^^^^^^^^ attempt to divide by zero + +error: attempt to divide by zero + --> $DIR/issue-8460-const2.rs:28:36 + | +LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); + | ^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:28:36 + | +LL | assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err()); + | ^^^^^^^^ attempt to divide by zero + +error: attempt to divide by zero + --> $DIR/issue-8460-const2.rs:31:36 + | +LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); + | ^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:31:36 + | +LL | assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err()); + | ^^^^^^^^ attempt to divide by zero + +error: attempt to calculate the remainder with overflow + --> $DIR/issue-8460-const2.rs:34:36 + | +LL | assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^^^ + +error: attempt to calculate the remainder with overflow + --> $DIR/issue-8460-const2.rs:36:36 + | +LL | assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^ + +error: attempt to calculate the remainder with overflow + --> $DIR/issue-8460-const2.rs:38:36 + | +LL | assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ + +error: attempt to calculate the remainder with overflow + --> $DIR/issue-8460-const2.rs:40:36 + | +LL | assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ + +error: attempt to calculate the remainder with overflow + --> $DIR/issue-8460-const2.rs:42:36 + | +LL | assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err()); + | ^^^^^^^^^^^^^ + +error: attempt to calculate the remainder with a divisor of zero + --> $DIR/issue-8460-const2.rs:44:36 + | +LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); + | ^^^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:44:36 + | +LL | assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err()); + | ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero + +error: attempt to calculate the remainder with a divisor of zero + --> $DIR/issue-8460-const2.rs:47:36 + | +LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); + | ^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:47:36 + | +LL | assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err()); + | ^^^^^^^ attempt to calculate the remainder with a divisor of zero + +error: attempt to calculate the remainder with a divisor of zero + --> $DIR/issue-8460-const2.rs:50:36 + | +LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); + | ^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:50:36 + | +LL | assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err()); + | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero + +error: attempt to calculate the remainder with a divisor of zero + --> $DIR/issue-8460-const2.rs:53:36 + | +LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); + | ^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:53:36 + | +LL | assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err()); + | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero + +error: attempt to calculate the remainder with a divisor of zero + --> $DIR/issue-8460-const2.rs:56:36 + | +LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); + | ^^^^^^^^ + +error: this expression will panic at runtime + --> $DIR/issue-8460-const2.rs:56:36 + | +LL | assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err()); + | ^^^^^^^^ attempt to calculate the remainder with a divisor of zero + +error: aborting due to 30 previous errors + From dd323f8a72327aba0b4771ea08a8b007bba995ca Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Mon, 2 Sep 2019 17:28:37 -0400 Subject: [PATCH 14/14] Emit error on intrinsic to fn ptr casts --- src/librustc/infer/error_reporting/mod.rs | 3 +++ src/librustc/ty/error.rs | 5 +++++ src/librustc/ty/structural_impls.rs | 2 ++ src/librustc_typeck/check/cast.rs | 4 ++++ src/librustc_typeck/check/coercion.rs | 6 ++++++ src/test/ui/reify-intrinsic.rs | 15 +++++++++++++++ src/test/ui/reify-intrinsic.stderr | 22 ++++++++++++++++++++++ 7 files changed, 57 insertions(+) create mode 100644 src/test/ui/reify-intrinsic.rs create mode 100644 src/test/ui/reify-intrinsic.stderr diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 9be73cf3c6d16..e684ccfeeb7ed 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1636,6 +1636,9 @@ impl<'tcx> ObligationCause<'tcx> { TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => { Error0644("closure/generator type that references itself") } + TypeError::IntrinsicCast => { + Error0308("cannot coerce intrinsics to function pointers") + } _ => Error0308("mismatched types"), }, } diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index c70006b68d69a..fe8f94ab1d314 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -46,6 +46,8 @@ pub enum TypeError<'tcx> { ExistentialMismatch(ExpectedFound<&'tcx ty::List>>), ConstMismatch(ExpectedFound<&'tcx ty::Const<'tcx>>), + + IntrinsicCast, } #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Debug, Copy)] @@ -179,6 +181,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { ConstMismatch(ref values) => { write!(f, "expected `{}`, found `{}`", values.expected, values.found) } + IntrinsicCast => { + write!(f, "cannot coerce intrinsics to function pointers") + } } } } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 649a5244728ba..ec7cf1a13c596 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -748,6 +748,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { Sorts(ref x) => return tcx.lift(x).map(Sorts), ExistentialMismatch(ref x) => return tcx.lift(x).map(ExistentialMismatch), ConstMismatch(ref x) => return tcx.lift(x).map(ConstMismatch), + IntrinsicCast => IntrinsicCast, }) } } @@ -1338,6 +1339,7 @@ EnumTypeFoldableImpl! { (ty::error::TypeError::Sorts)(x), (ty::error::TypeError::ExistentialMismatch)(x), (ty::error::TypeError::ConstMismatch)(x), + (ty::error::TypeError::IntrinsicCast), } } diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 55e7a10f1aaa4..c216cc92b1e58 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -40,6 +40,7 @@ use rustc::ty::{self, Ty, TypeFoldable, TypeAndMut}; use rustc::ty::subst::SubstsRef; use rustc::ty::adjustment::AllowTwoPhase; use rustc::ty::cast::{CastKind, CastTy}; +use rustc::ty::error::TypeError; use rustc::middle::lang_items; use syntax::ast; use syntax_pos::Span; @@ -461,6 +462,9 @@ impl<'a, 'tcx> CastCheck<'tcx> { self.expr_ty, fcx.tcx.mk_fn_ptr(f), AllowTwoPhase::No); + if let Err(TypeError::IntrinsicCast) = res { + return Err(CastError::IllegalCast); + } if res.is_err() { return Err(CastError::NonScalar); } diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 61b9c2a15ba16..f2e1a6e29d6fc 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -70,6 +70,7 @@ use std::ops::Deref; use syntax::feature_gate; use syntax::symbol::sym; use syntax_pos; +use rustc_target::spec::abi::Abi; struct Coerce<'a, 'tcx> { fcx: &'a FnCtxt<'a, 'tcx>, @@ -689,6 +690,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> { match b.sty { ty::FnPtr(_) => { let a_sig = a.fn_sig(self.tcx); + // Intrinsics are not coercible to function pointers + if a_sig.abi() == Abi::RustIntrinsic || + a_sig.abi() == Abi::PlatformIntrinsic { + return Err(TypeError::IntrinsicCast); + } let InferOk { value: a_sig, mut obligations } = self.normalize_associated_types_in_as_infer_ok(self.cause.span, &a_sig); diff --git a/src/test/ui/reify-intrinsic.rs b/src/test/ui/reify-intrinsic.rs new file mode 100644 index 0000000000000..09baa059e5567 --- /dev/null +++ b/src/test/ui/reify-intrinsic.rs @@ -0,0 +1,15 @@ +// check-fail + +#![feature(intrinsics)] + +fn a() { + let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute; + //~^ ERROR cannot coerce +} + +fn b() { + let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize; + //~^ ERROR casting +} + +fn main() {} diff --git a/src/test/ui/reify-intrinsic.stderr b/src/test/ui/reify-intrinsic.stderr new file mode 100644 index 0000000000000..4a1bd77cf7ee9 --- /dev/null +++ b/src/test/ui/reify-intrinsic.stderr @@ -0,0 +1,22 @@ +error[E0308]: cannot coerce intrinsics to function pointers + --> $DIR/reify-intrinsic.rs:6:64 + | +LL | let _: unsafe extern "rust-intrinsic" fn(isize) -> usize = std::mem::transmute; + | ^^^^^^^^^^^^^^^^^^^ + | | + | cannot coerce intrinsics to function pointers + | help: use parentheses to call this function: `std::mem::transmute(...)` + | + = note: expected type `unsafe extern "rust-intrinsic" fn(isize) -> usize` + found type `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` + +error[E0606]: casting `unsafe extern "rust-intrinsic" fn(_) -> _ {std::intrinsics::transmute::<_, _>}` as `unsafe extern "rust-intrinsic" fn(isize) -> usize` is invalid + --> $DIR/reify-intrinsic.rs:11:13 + | +LL | let _ = std::mem::transmute as unsafe extern "rust-intrinsic" fn(isize) -> usize; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + +Some errors have detailed explanations: E0308, E0606. +For more information about an error, try `rustc --explain E0308`.