From 507381ed0367f27e8804a1da33f8565c96a260ce Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Sat, 13 Oct 2018 23:38:31 +0200 Subject: Fix ICE and report a human readable error --- src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs | 5 +++++ src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr | 10 ++++++++++ 2 files changed, 15 insertions(+) create mode 100644 src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs create mode 100644 src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr (limited to 'src/test') diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs new file mode 100644 index 00000000000..3e42cb8c1b0 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.rs @@ -0,0 +1,5 @@ +const fn foo(a: i32) -> Vec { + vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn +} + +fn main() {} diff --git a/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr new file mode 100644 index 00000000000..f6b704370b6 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/bad_const_fn_body_ice.stderr @@ -0,0 +1,10 @@ +error: heap allocations are not allowed in const fn + --> $DIR/bad_const_fn_body_ice.rs:2:5 + | +LL | vec![1, 2, 3] //~ ERROR heap allocations are not allowed in const fn + | ^^^^^^^^^^^^^ + | + = 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 previous error + -- cgit 1.4.1-3-g733a5 From 2456f330d508b223d8cfcada8652ad37b647996a Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Mon, 15 Oct 2018 20:10:16 +0200 Subject: Try to trigger some error cases --- src/test/ui/consts/min_const_fn/cast_errors.rs | 14 ++++++++++ src/test/ui/consts/min_const_fn/cast_errors.stderr | 32 ++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 src/test/ui/consts/min_const_fn/cast_errors.rs create mode 100644 src/test/ui/consts/min_const_fn/cast_errors.stderr (limited to 'src/test') diff --git a/src/test/ui/consts/min_const_fn/cast_errors.rs b/src/test/ui/consts/min_const_fn/cast_errors.rs new file mode 100644 index 00000000000..36827b1b6b0 --- /dev/null +++ b/src/test/ui/consts/min_const_fn/cast_errors.rs @@ -0,0 +1,14 @@ +fn main() {} + +const fn unsize(x: &[u8; 3]) -> &[u8] { x } +//~^ ERROR unsizing casts are not allowed in const fn +const fn closure() -> fn() { || {} } +//~^ ERROR function pointers in const fn are unstable +const fn closure2() { + (|| {}) as fn(); +//~^ ERROR function pointers in const fn are unstable +} +const fn reify(f: fn()) -> unsafe fn() { f } +//~^ ERROR function pointers in const fn are unstable +const fn reify2() { main as unsafe fn(); } +//~^ ERROR function pointers in const fn are unstable \ No newline at end of file diff --git a/src/test/ui/consts/min_const_fn/cast_errors.stderr b/src/test/ui/consts/min_const_fn/cast_errors.stderr new file mode 100644 index 00000000000..ba980b7aacb --- /dev/null +++ b/src/test/ui/consts/min_const_fn/cast_errors.stderr @@ -0,0 +1,32 @@ +error: unsizing casts are not allowed in const fn + --> $DIR/cast_errors.rs:3:41 + | +LL | const fn unsize(x: &[u8; 3]) -> &[u8] { x } + | ^ + +error: function pointers in const fn are unstable + --> $DIR/cast_errors.rs:5:23 + | +LL | const fn closure() -> fn() { || {} } + | ^^^^ + +error: function pointers in const fn are unstable + --> $DIR/cast_errors.rs:8:5 + | +LL | (|| {}) as fn(); + | ^^^^^^^^^^^^^^^ + +error: function pointers in const fn are unstable + --> $DIR/cast_errors.rs:11:28 + | +LL | const fn reify(f: fn()) -> unsafe fn() { f } + | ^^^^^^^^^^^ + +error: function pointers in const fn are unstable + --> $DIR/cast_errors.rs:13:21 + | +LL | const fn reify2() { main as unsafe fn(); } + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 5 previous errors + -- cgit 1.4.1-3-g733a5 From 007390c21cc5e5e8705d455d20fba1df13bd7362 Mon Sep 17 00:00:00 2001 From: Oliver S̶c̶h̶n̶e̶i̶d̶e̶r Scherer Date: Mon, 15 Oct 2018 20:30:11 +0200 Subject: Add trailing newline to satisfy tidy --- src/test/ui/consts/min_const_fn/cast_errors.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/test') diff --git a/src/test/ui/consts/min_const_fn/cast_errors.rs b/src/test/ui/consts/min_const_fn/cast_errors.rs index 36827b1b6b0..8648cd35387 100644 --- a/src/test/ui/consts/min_const_fn/cast_errors.rs +++ b/src/test/ui/consts/min_const_fn/cast_errors.rs @@ -11,4 +11,4 @@ const fn closure2() { const fn reify(f: fn()) -> unsafe fn() { f } //~^ ERROR function pointers in const fn are unstable const fn reify2() { main as unsafe fn(); } -//~^ ERROR function pointers in const fn are unstable \ No newline at end of file +//~^ ERROR function pointers in const fn are unstable -- cgit 1.4.1-3-g733a5 From 0a858dc859f828af2c578bcf23418dd14c767f3c Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 17 Oct 2018 23:51:01 +0100 Subject: Don't warn about parentheses on `match (return)` --- src/librustc_lint/unused.rs | 13 ++++++++----- src/test/ui/lint/no-unused-parens-return-block.rs | 6 ++++++ 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 src/test/ui/lint/no-unused-parens-return-block.rs (limited to 'src/test') diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs index 76717548521..4cf2072e792 100644 --- a/src/librustc_lint/unused.rs +++ b/src/librustc_lint/unused.rs @@ -276,10 +276,13 @@ impl UnusedParens { cx: &EarlyContext, value: &ast::Expr, msg: &str, - struct_lit_needs_parens: bool) { + followed_by_block: bool) { if let ast::ExprKind::Paren(ref inner) = value.node { - let necessary = struct_lit_needs_parens && - parser::contains_exterior_struct_lit(&inner); + let necessary = followed_by_block && if let ast::ExprKind::Ret(_) = inner.node { + true + } else { + parser::contains_exterior_struct_lit(&inner) + }; if !necessary { let pattern = pprust::expr_to_string(value); Self::remove_outer_parens(cx, value.span, &pattern, msg); @@ -343,7 +346,7 @@ impl LintPass for UnusedParens { impl EarlyLintPass for UnusedParens { fn check_expr(&mut self, cx: &EarlyContext, e: &ast::Expr) { use syntax::ast::ExprKind::*; - let (value, msg, struct_lit_needs_parens) = match e.node { + let (value, msg, followed_by_block) = match e.node { If(ref cond, ..) => (cond, "`if` condition", true), While(ref cond, ..) => (cond, "`while` condition", true), IfLet(_, ref cond, ..) => (cond, "`if let` head expression", true), @@ -380,7 +383,7 @@ impl EarlyLintPass for UnusedParens { return; } }; - self.check_unused_parens_expr(cx, &value, msg, struct_lit_needs_parens); + self.check_unused_parens_expr(cx, &value, msg, followed_by_block); } fn check_pat(&mut self, cx: &EarlyContext, p: &ast::Pat) { diff --git a/src/test/ui/lint/no-unused-parens-return-block.rs b/src/test/ui/lint/no-unused-parens-return-block.rs new file mode 100644 index 00000000000..fc8dbb743e1 --- /dev/null +++ b/src/test/ui/lint/no-unused-parens-return-block.rs @@ -0,0 +1,6 @@ +// run-pass + +fn main() { + match (return) {} // ok + if (return) {} // ok +} -- cgit 1.4.1-3-g733a5 From 40bba70823466eb1458a4fd99a4f644411b4eae4 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 18 Oct 2018 10:35:01 +0100 Subject: Make warnings into errors --- src/test/ui/lint/no-unused-parens-return-block.rs | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/test') diff --git a/src/test/ui/lint/no-unused-parens-return-block.rs b/src/test/ui/lint/no-unused-parens-return-block.rs index fc8dbb743e1..37dc519a204 100644 --- a/src/test/ui/lint/no-unused-parens-return-block.rs +++ b/src/test/ui/lint/no-unused-parens-return-block.rs @@ -1,5 +1,8 @@ // run-pass +#![deny(unused_parens)] +#![allow(unreachable_code)] + fn main() { match (return) {} // ok if (return) {} // ok -- cgit 1.4.1-3-g733a5 From ef1a40d5fec8678c4ae51cf2dcbed96934182b8c Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Fri, 12 Oct 2018 15:16:29 +0100 Subject: Propagate bounds from generators --- .../borrow_check/nll/region_infer/mod.rs | 12 ++++-------- src/librustc_mir/borrow_check/nll/type_check/mod.rs | 15 ++++++--------- .../borrow_check/nll/universal_regions.rs | 4 ++-- .../generator-region-requirements.ast.stderr | 12 ++++++++++++ .../generator-region-requirements.nll.stderr | 12 ++++++++++++ .../ui/generator/generator-region-requirements.rs | 21 +++++++++++++++++++++ 6 files changed, 57 insertions(+), 19 deletions(-) create mode 100644 src/test/ui/generator/generator-region-requirements.ast.stderr create mode 100644 src/test/ui/generator/generator-region-requirements.nll.stderr create mode 100644 src/test/ui/generator/generator-region-requirements.rs (limited to 'src/test') diff --git a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs index dd8a7f19a63..0fabcfe4564 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/mod.rs @@ -1268,7 +1268,7 @@ pub trait ClosureRegionRequirementsExt<'gcx, 'tcx> { tcx: TyCtxt<'_, 'gcx, 'tcx>, location: Location, closure_def_id: DefId, - closure_substs: ty::ClosureSubsts<'tcx>, + closure_substs: &'tcx ty::subst::Substs<'tcx>, ) -> Vec>; fn subst_closure_mapping( @@ -1299,23 +1299,19 @@ impl<'gcx, 'tcx> ClosureRegionRequirementsExt<'gcx, 'tcx> for ClosureRegionRequi tcx: TyCtxt<'_, 'gcx, 'tcx>, location: Location, closure_def_id: DefId, - closure_substs: ty::ClosureSubsts<'tcx>, + closure_substs: &'tcx ty::subst::Substs<'tcx>, ) -> Vec> { debug!( "apply_requirements(location={:?}, closure_def_id={:?}, closure_substs={:?})", location, closure_def_id, closure_substs ); - // Get Tu. - let user_closure_ty = tcx.mk_closure(closure_def_id, closure_substs); - debug!("apply_requirements: user_closure_ty={:?}", user_closure_ty); - - // Extract the values of the free regions in `user_closure_ty` + // Extract the values of the free regions in `closure_substs` // into a vector. These are the regions that we will be // relating to one another. let closure_mapping = &UniversalRegions::closure_mapping( tcx, - user_closure_ty, + closure_substs, self.num_external_vids, tcx.closure_base_def_id(closure_def_id), ); diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index 1e79bc272e4..c5758cde949 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -42,7 +42,7 @@ use rustc::traits::query::type_op::custom::CustomTypeOp; use rustc::traits::query::{Fallible, NoSolution}; use rustc::traits::{ObligationCause, PredicateObligations}; use rustc::ty::fold::TypeFoldable; -use rustc::ty::subst::{Subst, UnpackedKind}; +use rustc::ty::subst::{Subst, Substs, UnpackedKind}; use rustc::ty::{self, RegionVid, ToPolyTraitRef, Ty, TyCtxt, TyKind}; use std::rc::Rc; use std::{fmt, iter}; @@ -2075,12 +2075,9 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { // desugaring. A closure gets desugared to a struct, and // these extra requirements are basically like where // clauses on the struct. - AggregateKind::Closure(def_id, substs) => { - self.prove_closure_bounds(tcx, *def_id, *substs, location) - } - - AggregateKind::Generator(def_id, substs, _) => { - tcx.predicates_of(*def_id).instantiate(tcx, substs.substs) + AggregateKind::Closure(def_id, ty::ClosureSubsts { substs }) + | AggregateKind::Generator(def_id, ty::GeneratorSubsts { substs }, _) => { + self.prove_closure_bounds(tcx, *def_id, substs, location) } AggregateKind::Array(_) | AggregateKind::Tuple => ty::InstantiatedPredicates::empty(), @@ -2096,7 +2093,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { &mut self, tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId, - substs: ty::ClosureSubsts<'tcx>, + substs: &'tcx Substs<'tcx>, location: Location, ) -> ty::InstantiatedPredicates<'tcx> { if let Some(closure_region_requirements) = @@ -2155,7 +2152,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> { ); } - tcx.predicates_of(def_id).instantiate(tcx, substs.substs) + tcx.predicates_of(def_id).instantiate(tcx, substs) } fn prove_trait_ref( diff --git a/src/librustc_mir/borrow_check/nll/universal_regions.rs b/src/librustc_mir/borrow_check/nll/universal_regions.rs index eb6f1a0677b..c54a4f96b7d 100644 --- a/src/librustc_mir/borrow_check/nll/universal_regions.rs +++ b/src/librustc_mir/borrow_check/nll/universal_regions.rs @@ -232,13 +232,13 @@ impl<'tcx> UniversalRegions<'tcx> { /// `V[1]: V[2]`. pub fn closure_mapping( tcx: TyCtxt<'_, '_, 'tcx>, - closure_ty: Ty<'tcx>, + closure_substs: &'tcx Substs<'tcx>, expected_num_vars: usize, closure_base_def_id: DefId, ) -> IndexVec> { let mut region_mapping = IndexVec::with_capacity(expected_num_vars); region_mapping.push(tcx.types.re_static); - tcx.for_each_free_region(&closure_ty, |fr| { + tcx.for_each_free_region(&closure_substs, |fr| { region_mapping.push(fr); }); diff --git a/src/test/ui/generator/generator-region-requirements.ast.stderr b/src/test/ui/generator/generator-region-requirements.ast.stderr new file mode 100644 index 00000000000..6a423aea7ec --- /dev/null +++ b/src/test/ui/generator/generator-region-requirements.ast.stderr @@ -0,0 +1,12 @@ +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/generator-region-requirements.rs:15:51 + | +LL | fn dangle(x: &mut i32) -> &'static mut i32 { + | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32` +... +LL | GeneratorState::Complete(c) => return c, + | ^ lifetime `'static` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/generator/generator-region-requirements.nll.stderr b/src/test/ui/generator/generator-region-requirements.nll.stderr new file mode 100644 index 00000000000..5d1050dc352 --- /dev/null +++ b/src/test/ui/generator/generator-region-requirements.nll.stderr @@ -0,0 +1,12 @@ +error[E0621]: explicit lifetime required in the type of `x` + --> $DIR/generator-region-requirements.rs:11:9 + | +LL | fn dangle(x: &mut i32) -> &'static mut i32 { + | -------- help: add explicit lifetime `'static` to the type of `x`: `&'static mut i32` +... +LL | x + | ^ lifetime `'static` required + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0621`. diff --git a/src/test/ui/generator/generator-region-requirements.rs b/src/test/ui/generator/generator-region-requirements.rs new file mode 100644 index 00000000000..59e7841309c --- /dev/null +++ b/src/test/ui/generator/generator-region-requirements.rs @@ -0,0 +1,21 @@ +// revisions: ast nll +// ignore-compare-mode-nll + +#![feature(generators, generator_trait)] +#![cfg_attr(nll, feature(nll))] +use std::ops::{Generator, GeneratorState}; + +fn dangle(x: &mut i32) -> &'static mut i32 { + let mut g = || { + yield; + x + }; + loop { + match unsafe { g.resume() } { + GeneratorState::Complete(c) => return c, + GeneratorState::Yielded(_) => (), + } + } +} + +fn main() {} -- cgit 1.4.1-3-g733a5