Skip to content

Prohibit parenthesized params in more types. #41856

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/librustc/lint/builtin.rs
Original file line number Diff line number Diff line change
@@ -236,6 +236,12 @@ declare_lint! {
"detects missing fragment specifiers in unused `macro_rules!` patterns"
}

declare_lint! {
pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
Warn,
"detects parenthesized generic parameters in type and module names"
}

declare_lint! {
pub DEPRECATED,
Warn,
@@ -286,6 +292,7 @@ impl LintPass for HardwiredLints {
LEGACY_IMPORTS,
LEGACY_CONSTRUCTOR_VISIBILITY,
MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
DEPRECATED
)
}
4 changes: 4 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
@@ -250,6 +250,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
id: LintId::of(MISSING_FRAGMENT_SPECIFIER),
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>",
36 changes: 32 additions & 4 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
@@ -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};
@@ -161,10 +162,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
@@ -375,6 +373,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,
@@ -407,6 +407,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,
@@ -628,6 +630,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() {
@@ -948,6 +957,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")
@@ -970,6 +983,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");
4 changes: 3 additions & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
@@ -4495,7 +4495,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, &[][..])
}
5 changes: 4 additions & 1 deletion src/test/compile-fail/issue-22560.rs
Original file line number Diff line number Diff line change
@@ -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() { }
36 changes: 36 additions & 0 deletions src/test/compile-fail/issue-32995-2.rs
Original file line number Diff line number Diff line change
@@ -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
62 changes: 62 additions & 0 deletions src/test/compile-fail/issue-32995.rs
Original file line number Diff line number Diff line change
@@ -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
}