about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2017-05-29 11:32:14 +0000
committerbors <bors@rust-lang.org>2017-05-29 11:32:14 +0000
commit03bed655142dd5e42ba4539de53b3663d8a123e0 (patch)
tree2ee6c7a5bbe59f2f62675d772ecb7ec1d49f2212
parentbe5f4fe6cc7179b900eb31ee3e9235fd12bd04c7 (diff)
parent99993780dc2db803877ed700cbf315246fc3ad7f (diff)
downloadrust-03bed655142dd5e42ba4539de53b3663d8a123e0.tar.gz
rust-03bed655142dd5e42ba4539de53b3663d8a123e0.zip
Auto merge of #41856 - qnighy:prohibit-parenthesized-params-in-more-types, r=arielb1
Prohibit parenthesized params in more types.

Prohibit parenthesized parameters in primitive types, type parameters, `Self`, etc.

Fixes #32995.
-rw-r--r--src/librustc/lint/builtin.rs7
-rw-r--r--src/librustc_lint/lib.rs4
-rw-r--r--src/librustc_typeck/astconv.rs36
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/test/compile-fail/issue-22560.rs5
-rw-r--r--src/test/compile-fail/issue-32995-2.rs36
-rw-r--r--src/test/compile-fail/issue-32995.rs62
7 files changed, 148 insertions, 6 deletions
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 07140f71aeb..0bc1be70174 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -243,6 +243,12 @@ declare_lint! {
 }
 
 declare_lint! {
+    pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
+    Warn,
+    "detects parenthesized generic parameters in type and module names"
+}
+
+declare_lint! {
     pub DEPRECATED,
     Warn,
     "detects use of deprecated items"
@@ -293,6 +299,7 @@ impl LintPass for HardwiredLints {
             LEGACY_IMPORTS,
             LEGACY_CONSTRUCTOR_VISIBILITY,
             MISSING_FRAGMENT_SPECIFIER,
+            PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
             DEPRECATED
         )
     }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 479c7206cb4..d8f29768ccd 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -253,6 +253,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
             reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>",
         },
         FutureIncompatibleInfo {
+            id: LintId::of(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES),
+            reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
+        },
+        FutureIncompatibleInfo {
             id: LintId::of(ANONYMOUS_PARAMETERS),
             reference: "issue #41686 <https://github.com/rust-lang/rust/issues/41686>",
         },
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index 0c9d74df248..c9eb9807c41 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -22,6 +22,7 @@ use rustc::ty::subst::{Kind, Subst, Substs};
 use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::wf::object_region_bounds;
+use rustc::lint::builtin::PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES;
 use rustc_back::slice;
 use require_c_abi_if_variadic;
 use util::common::{ErrorReported, FN_OUTPUT_NAME};
@@ -156,10 +157,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         match item_segment.parameters {
             hir::AngleBracketedParameters(_) => {}
             hir::ParenthesizedParameters(..) => {
-                struct_span_err!(tcx.sess, span, E0214,
-                          "parenthesized parameters may only be used with a trait")
-                    .span_label(span, "only traits may use parentheses")
-                    .emit();
+                self.prohibit_parenthesized_params(item_segment, true);
 
                 return Substs::for_item(tcx, def_id, |_, _| {
                     tcx.types.re_static
@@ -370,6 +368,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         self_ty: Ty<'tcx>)
         -> ty::TraitRef<'tcx>
     {
+        self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
+
         let trait_def_id = self.trait_def_id(trait_ref);
         self.ast_path_to_mono_trait_ref(trait_ref.path.span,
                                         trait_def_id,
@@ -402,6 +402,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
 
         debug!("ast_path_to_poly_trait_ref({:?}, def_id={:?})", trait_ref, trait_def_id);
 
+        self.prohibit_type_params(trait_ref.path.segments.split_last().unwrap().1);
+
         let (substs, assoc_bindings) =
             self.create_substs_for_ast_trait_ref(trait_ref.path.span,
                                                  trait_def_id,
@@ -623,6 +625,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                                                         dummy_self,
                                                         &mut projection_bounds);
 
+        for trait_bound in trait_bounds[1..].iter() {
+            // Sanity check for non-principal trait bounds
+            self.instantiate_poly_trait_ref(trait_bound,
+                                            dummy_self,
+                                            &mut vec![]);
+        }
+
         let (auto_traits, trait_bounds) = split_auto_traits(tcx, &trait_bounds[1..]);
 
         if !trait_bounds.is_empty() {
@@ -938,6 +947,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
 
     pub fn prohibit_type_params(&self, segments: &[hir::PathSegment]) {
         for segment in segments {
+            if let hir::ParenthesizedParameters(_) = segment.parameters {
+                self.prohibit_parenthesized_params(segment, false);
+                break;
+            }
             for typ in segment.parameters.types() {
                 struct_span_err!(self.tcx().sess, typ.span, E0109,
                                  "type parameters are not allowed on this type")
@@ -960,6 +973,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
         }
     }
 
+    pub fn prohibit_parenthesized_params(&self, segment: &hir::PathSegment, emit_error: bool) {
+        if let hir::ParenthesizedParameters(ref data) = segment.parameters {
+            if emit_error {
+                struct_span_err!(self.tcx().sess, data.span, E0214,
+                          "parenthesized parameters may only be used with a trait")
+                    .span_label(data.span, "only traits may use parentheses")
+                    .emit();
+            } else {
+                let msg = "parenthesized parameters may only be used with a trait".to_string();
+                self.tcx().sess.add_lint(PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
+                                         ast::CRATE_NODE_ID, data.span, msg);
+            }
+        }
+    }
+
     pub fn prohibit_projection(&self, span: Span) {
         let mut err = struct_span_err!(self.tcx().sess, span, E0229,
                                        "associated type bindings are not allowed here");
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 1ad3914854d..b5c2780e9a7 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4536,7 +4536,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     (&data.lifetimes[..], &data.types[..], data.infer_types, &data.bindings[..])
                 }
                 Some(&hir::ParenthesizedParameters(_)) => {
-                    span_bug!(span, "parenthesized parameters cannot appear in ExprPath");
+                    AstConv::prohibit_parenthesized_params(self, &segment.as_ref().unwrap().0,
+                                                           false);
+                    (&[][..], &[][..], true, &[][..])
                 }
                 None => (&[][..], &[][..], true, &[][..])
             }
diff --git a/src/test/compile-fail/issue-22560.rs b/src/test/compile-fail/issue-22560.rs
index 2ad804fc8ce..eb5c6076440 100644
--- a/src/test/compile-fail/issue-22560.rs
+++ b/src/test/compile-fail/issue-22560.rs
@@ -19,7 +19,10 @@ type Test = Add +
             //~| ERROR E0191
             //~| NOTE missing associated type `Output` value
             Sub;
-            //~^ ERROR E0225
+            //~^ ERROR E0393
+            //~| NOTE missing reference to `RHS`
+            //~| NOTE because of the default `Self` reference, type parameters must be specified on object types
+            //~| ERROR E0225
             //~| NOTE non-Send/Sync additional trait
 
 fn main() { }
diff --git a/src/test/compile-fail/issue-32995-2.rs b/src/test/compile-fail/issue-32995-2.rs
new file mode 100644
index 00000000000..cb68d52ef96
--- /dev/null
+++ b/src/test/compile-fail/issue-32995-2.rs
@@ -0,0 +1,36 @@
+// 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.
+
+#![deny(parenthesized_params_in_types_and_modules)]
+//~^ NOTE lint level defined here
+//~| NOTE lint level defined here
+//~| NOTE lint level defined here
+#![allow(dead_code, unused_variables)]
+#![feature(conservative_impl_trait)]
+
+fn main() {
+    { fn f<X: ::std::marker()::Send>() {} }
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+
+    { fn f() -> impl ::std::marker()::Send { } }
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+}
+
+#[derive(Clone)]
+struct X;
+
+impl ::std::marker()::Copy for X {}
+//~^ ERROR parenthesized parameters may only be used with a trait
+//~| WARN previously accepted
+//~| NOTE issue #42238
diff --git a/src/test/compile-fail/issue-32995.rs b/src/test/compile-fail/issue-32995.rs
new file mode 100644
index 00000000000..f2ed8bf53ea
--- /dev/null
+++ b/src/test/compile-fail/issue-32995.rs
@@ -0,0 +1,62 @@
+// 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.
+
+#![deny(parenthesized_params_in_types_and_modules)]
+//~^ NOTE lint level defined here
+//~| NOTE lint level defined here
+//~| NOTE lint level defined here
+//~| NOTE lint level defined here
+//~| NOTE lint level defined here
+//~| NOTE lint level defined here
+//~| NOTE lint level defined here
+#![allow(dead_code, unused_variables)]
+
+fn main() {
+    let x: usize() = 1;
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+
+    let b: ::std::boxed()::Box<_> = Box::new(1);
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+
+    macro_rules! pathexpr {
+        ($p:path) => { $p }
+    }
+
+    let p = pathexpr!(::std::str()::from_utf8)(b"foo").unwrap();
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+
+    let p = pathexpr!(::std::str::from_utf8())(b"foo").unwrap();
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+
+    let o : Box<::std::marker()::Send> = Box::new(1);
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+
+    let o : Box<Send + ::std::marker()::Sync> = Box::new(1);
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+}
+
+fn foo<X:Default>() {
+    let d : X() = Default::default();
+    //~^ ERROR parenthesized parameters may only be used with a trait
+    //~| WARN previously accepted
+    //~| NOTE issue #42238
+}