about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-06-29 02:30:53 +0000
committerbors <bors@rust-lang.org>2017-06-29 02:30:53 +0000
commit0816b94f02e1cd20031b764370ed74102963527d (patch)
treecd07bd265937919df4eb2f9cfd5992ed3c85ce08
parentc28cbfb127fb66846573955838c5ed1c920e7112 (diff)
parent5ed21f5d47c28e0e1541c037683becb90adabe65 (diff)
downloadrust-0816b94f02e1cd20031b764370ed74102963527d.tar.gz
rust-0816b94f02e1cd20031b764370ed74102963527d.zip
Auto merge of #42642 - venkatagiri:issue_42312, r=nikomatsakis
rustc_typeck: enforce argument type is sized

closes #42312

r? @nikomatsakis
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs12
-rw-r--r--src/librustc/traits/error_reporting.rs16
-rw-r--r--src/librustc/traits/mod.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs2
-rw-r--r--src/librustc_typeck/check/compare_method.rs4
-rw-r--r--src/librustc_typeck/check/dropck.rs2
-rw-r--r--src/librustc_typeck/check/mod.rs50
-rw-r--r--src/librustc_typeck/check/writeback.rs2
-rw-r--r--src/librustc_typeck/coherence/builtin.rs2
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/test/compile-fail/issue-23046.rs4
-rw-r--r--src/test/compile-fail/issue-38954.rs6
-rw-r--r--src/test/compile-fail/issue-42312.rs21
-rw-r--r--src/test/run-pass/associated-types-sugar-path.rs2
14 files changed, 61 insertions, 66 deletions
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index 7361d66428f..a684881c091 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use hir::{self, map, Local, Pat, Body};
+use hir::{self, Local, Pat, Body};
 use hir::intravisit::{self, Visitor, NestedVisitorMap};
 use infer::InferCtxt;
 use infer::type_variable::TypeVariableOrigin;
@@ -88,7 +88,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    pub fn need_type_info(&self, body_id: hir::BodyId, span: Span, ty: Ty<'tcx>) {
+    pub fn need_type_info(&self, body_id: Option<hir::BodyId>, span: Span, ty: Ty<'tcx>) {
         let ty = self.resolve_type_vars_if_possible(&ty);
         let name = self.extract_type_name(&ty);
 
@@ -103,11 +103,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             found_arg_pattern: None,
         };
 
-        // #40294: cause.body_id can also be a fn declaration.
-        // Currently, if it's anything other than NodeExpr, we just ignore it
-        match self.tcx.hir.find(body_id.node_id) {
-            Some(map::NodeExpr(expr)) => local_visitor.visit_expr(expr),
-            _ => ()
+        if let Some(body_id) = body_id {
+            let expr = self.tcx.hir.expect_expr(body_id.node_id);
+            local_visitor.visit_expr(expr);
         }
 
         if let Some(pattern) = local_visitor.found_arg_pattern {
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 2f260b0b9ee..e2e3d520d47 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -45,7 +45,8 @@ use syntax_pos::{DUMMY_SP, Span};
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     pub fn report_fulfillment_errors(&self,
-                                     errors: &Vec<FulfillmentError<'tcx>>) {
+                                     errors: &Vec<FulfillmentError<'tcx>>,
+                                     body_id: Option<hir::BodyId>) {
         #[derive(Debug)]
         struct ErrorDescriptor<'tcx> {
             predicate: ty::Predicate<'tcx>,
@@ -105,7 +106,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
 
         for (error, suppressed) in errors.iter().zip(is_suppressed) {
             if !suppressed {
-                self.report_fulfillment_error(error);
+                self.report_fulfillment_error(error, body_id);
             }
         }
     }
@@ -148,7 +149,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         false
     }
 
-    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>) {
+    fn report_fulfillment_error(&self, error: &FulfillmentError<'tcx>,
+                                body_id: Option<hir::BodyId>) {
         debug!("report_fulfillment_errors({:?})", error);
         match error.code {
             FulfillmentErrorCode::CodeSelectionError(ref e) => {
@@ -158,7 +160,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 self.report_projection_error(&error.obligation, e);
             }
             FulfillmentErrorCode::CodeAmbiguity => {
-                self.maybe_report_ambiguity(&error.obligation);
+                self.maybe_report_ambiguity(&error.obligation, body_id);
             }
             FulfillmentErrorCode::CodeSubtypeError(ref expected_found, ref err) => {
                 self.report_mismatched_types(&error.obligation.cause,
@@ -869,14 +871,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 }
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>) {
+    fn maybe_report_ambiguity(&self, obligation: &PredicateObligation<'tcx>,
+                              body_id: Option<hir::BodyId>) {
         // Unable to successfully determine, probably means
         // insufficient type information, but could mean
         // ambiguous impls. The latter *ought* to be a
         // coherence violation, so we don't report it here.
 
         let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
-        let body_id = hir::BodyId { node_id: obligation.cause.body_id };
         let span = obligation.cause.span;
 
         debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
@@ -953,7 +955,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                     let &SubtypePredicate { a_is_expected: _, a, b } = data.skip_binder();
                     // both must be type variables, or the other would've been instantiated
                     assert!(a.is_ty_var() && b.is_ty_var());
-                    self.need_type_info(hir::BodyId { node_id: obligation.cause.body_id },
+                    self.need_type_info(body_id,
                                         obligation.cause.span,
                                         a);
                 }
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index 249cf6b1e27..c128438aea0 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -509,7 +509,7 @@ pub fn normalize_param_env_or_error<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         ) {
             Ok(predicates) => predicates,
             Err(errors) => {
-                infcx.report_fulfillment_errors(&errors);
+                infcx.report_fulfillment_errors(&errors, None);
                 // An unnormalized env is better than nothing.
                 return elaborated_env;
             }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 91d6ce60b39..68b687a2e61 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -996,7 +996,7 @@ impl MirPass for QualifyAndPromoteConstants {
                                               tcx.require_lang_item(lang_items::SyncTraitLangItem),
                                               cause);
                 if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
-                    infcx.report_fulfillment_errors(&err);
+                    infcx.report_fulfillment_errors(&err, None);
                 }
             });
         }
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index fd5147d76e8..bf134f9547d 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -328,7 +328,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // Check that all obligations are satisfied by the implementation's
         // version.
         if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(errors);
+            infcx.report_fulfillment_errors(errors, None);
             return Err(ErrorReported);
         }
 
@@ -793,7 +793,7 @@ pub fn compare_const_impl<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // Check that all obligations are satisfied by the implementation's
         // version.
         if let Err(ref errors) = inh.fulfillment_cx.borrow_mut().select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(errors);
+            infcx.report_fulfillment_errors(errors, None);
             return;
         }
 
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 93057f91997..ed22cd1333e 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -110,7 +110,7 @@ fn ensure_drop_params_and_item_params_correspond<'a, 'tcx>(
 
         if let Err(ref errors) = fulfillment_cx.select_all_or_error(&infcx) {
             // this could be reached when we get lazy normalization
-            infcx.report_fulfillment_errors(errors);
+            infcx.report_fulfillment_errors(errors, None);
             return Err(ErrorReported);
         }
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index dd488f0c4fe..34cf1d7f96b 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -217,6 +217,8 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     /// environment is for an item or something where the "callee" is
     /// not clear.
     implicit_region_bound: Option<ty::Region<'tcx>>,
+
+    body_id: Option<hir::BodyId>,
 }
 
 impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
@@ -605,6 +607,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
             deferred_cast_checks: RefCell::new(Vec::new()),
             anon_types: RefCell::new(NodeMap()),
             implicit_region_bound,
+            body_id,
         }
     }
 
@@ -993,16 +996,17 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
 
     // Add formal parameters.
     for (arg_ty, arg) in fn_sig.inputs().iter().zip(&body.arguments) {
-        // The type of the argument must be well-formed.
-        //
-        // NB -- this is now checked in wfcheck, but that
-        // currently only results in warnings, so we issue an
-        // old-style WF obligation here so that we still get the
-        // errors that we used to get.
-        fcx.register_old_wf_obligation(arg_ty, arg.pat.span, traits::MiscObligation);
-
         // Check the pattern.
         fcx.check_pat_arg(&arg.pat, arg_ty, true);
+
+        // Check that argument is Sized.
+        // The check for a non-trivial pattern is a hack to avoid duplicate warnings
+        // for simple cases like `fn foo(x: Trait)`,
+        // where we would error once on the parameter as a whole, and once on the binding `x`.
+        if arg.pat.simple_name().is_none() {
+            fcx.require_type_is_sized(arg_ty, decl.output.span(), traits::MiscObligation);
+        }
+
         fcx.write_ty(arg.id, arg_ty);
     }
 
@@ -1980,17 +1984,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
     /// Registers an obligation for checking later, during regionck, that the type `ty` must
     /// outlive the region `r`.
-    pub fn register_region_obligation(&self,
-                                      ty: Ty<'tcx>,
-                                      region: ty::Region<'tcx>,
-                                      cause: traits::ObligationCause<'tcx>)
-    {
-        let mut fulfillment_cx = self.fulfillment_cx.borrow_mut();
-        fulfillment_cx.register_region_obligation(ty, region, cause);
-    }
-
-    /// Registers an obligation for checking later, during regionck, that the type `ty` must
-    /// outlive the region `r`.
     pub fn register_wf_obligation(&self,
                                   ty: Ty<'tcx>,
                                   span: Span,
@@ -2003,21 +1996,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                         ty::Predicate::WellFormed(ty)));
     }
 
-    pub fn register_old_wf_obligation(&self,
-                                      ty: Ty<'tcx>,
-                                      span: Span,
-                                      code: traits::ObligationCauseCode<'tcx>)
-    {
-        // Registers an "old-style" WF obligation that uses the
-        // implicator code.  This is basically a buggy version of
-        // `register_wf_obligation` that is being kept around
-        // temporarily just to help with phasing in the newer rules.
-        //
-        // FIXME(#27579) all uses of this should be migrated to register_wf_obligation eventually
-        let cause = traits::ObligationCause::new(span, self.body_id, code);
-        self.register_region_obligation(ty, self.tcx.types.re_empty, cause);
-    }
-
     /// Registers obligations that all types appearing in `substs` are well-formed.
     pub fn add_wf_bounds(&self, substs: &Substs<'tcx>, expr: &hir::Expr)
     {
@@ -2145,7 +2123,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
         match fulfillment_cx.select_all_or_error(self) {
             Ok(()) => { }
-            Err(errors) => { self.report_fulfillment_errors(&errors); }
+            Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
         }
     }
 
@@ -2153,7 +2131,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     fn select_obligations_where_possible(&self) {
         match self.fulfillment_cx.borrow_mut().select_where_possible(self) {
             Ok(()) => { }
-            Err(errors) => { self.report_fulfillment_errors(&errors); }
+            Err(errors) => { self.report_fulfillment_errors(&errors, self.inh.body_id); }
         }
     }
 
diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs
index 4af262bcb78..81e5dae5477 100644
--- a/src/librustc_typeck/check/writeback.rs
+++ b/src/librustc_typeck/check/writeback.rs
@@ -377,7 +377,7 @@ impl<'cx, 'gcx, 'tcx> Resolver<'cx, 'gcx, 'tcx> {
 
     fn report_error(&self, t: Ty<'tcx>) {
         if !self.tcx.sess.has_errors() {
-            self.infcx.need_type_info(self.body.id(), self.span.to_span(&self.tcx), t);
+            self.infcx.need_type_info(Some(self.body.id()), self.span.to_span(&self.tcx), t);
         }
     }
 }
diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs
index ccbc0299041..9305eff1436 100644
--- a/src/librustc_typeck/coherence/builtin.rs
+++ b/src/librustc_typeck/coherence/builtin.rs
@@ -386,7 +386,7 @@ pub fn coerce_unsized_info<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         // Check that all transitive obligations are satisfied.
         if let Err(errors) = fulfill_cx.select_all_or_error(&infcx) {
-            infcx.report_fulfillment_errors(&errors);
+            infcx.report_fulfillment_errors(&errors, None);
         }
 
         // Finally, resolve all regions.
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 519e1ca6e5a..2857b5fb5e0 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -166,7 +166,7 @@ fn require_same_types<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         match fulfill_cx.select_all_or_error(infcx) {
             Ok(()) => true,
             Err(errors) => {
-                infcx.report_fulfillment_errors(&errors);
+                infcx.report_fulfillment_errors(&errors, None);
                 false
             }
         }
diff --git a/src/test/compile-fail/issue-23046.rs b/src/test/compile-fail/issue-23046.rs
index 28109747b75..129f7c8b1ea 100644
--- a/src/test/compile-fail/issue-23046.rs
+++ b/src/test/compile-fail/issue-23046.rs
@@ -24,7 +24,7 @@ pub fn let_<'var, VAR, F: for<'v: 'var> Fn(Expr<'v, VAR>) -> Expr<'v, VAR>>
 }
 
 fn main() {
-    let ex = |x| {
-        let_(add(x,x), |y| { //~ ERROR type annotations needed
+    let ex = |x| { //~ ERROR type annotations needed
+        let_(add(x,x), |y| {
             let_(add(x, x), |x|x)})};
 }
diff --git a/src/test/compile-fail/issue-38954.rs b/src/test/compile-fail/issue-38954.rs
index 65b17a3db0b..896728b6da0 100644
--- a/src/test/compile-fail/issue-38954.rs
+++ b/src/test/compile-fail/issue-38954.rs
@@ -8,9 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(rustc_attrs)]
-
 fn _test(ref _p: str) {}
+//~^ ERROR the trait bound `str: std::marker::Sized` is not satisfied [E0277]
 
-#[rustc_error]
-fn main() { } //~ ERROR compilation successful
+fn main() { }
diff --git a/src/test/compile-fail/issue-42312.rs b/src/test/compile-fail/issue-42312.rs
new file mode 100644
index 00000000000..06573b42b59
--- /dev/null
+++ b/src/test/compile-fail/issue-42312.rs
@@ -0,0 +1,21 @@
+// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::ops::Deref;
+
+pub trait Foo {
+    fn baz(_: Self::Target) where Self: Deref {}
+    //~^ ERROR `<Self as std::ops::Deref>::Target: std::marker::Sized` is not satisfied
+}
+
+pub fn f(_: ToString) {}
+//~^ ERROR the trait bound `std::string::ToString + 'static: std::marker::Sized` is not satisfied
+
+fn main() { }
diff --git a/src/test/run-pass/associated-types-sugar-path.rs b/src/test/run-pass/associated-types-sugar-path.rs
index 587fb3f80d6..d8d42f2cba2 100644
--- a/src/test/run-pass/associated-types-sugar-path.rs
+++ b/src/test/run-pass/associated-types-sugar-path.rs
@@ -15,8 +15,6 @@ use std::ops::Deref;
 pub trait Foo {
     type A;
     fn boo(&self) -> Self::A;
-
-    fn baz(_: Self::Target) where Self: Deref {}
 }
 
 impl Foo for isize {