Skip to content
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

Prohibit parenthesized params in more types. #41856

Merged
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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,
Expand Down Expand Up @@ -286,6 +292,7 @@ impl LintPass for HardwiredLints {
LEGACY_IMPORTS,
LEGACY_CONSTRUCTOR_VISIBILITY,
MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
DEPRECATED
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/librustc_lint/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>",
Expand Down
36 changes: 32 additions & 4 deletions src/librustc_typeck/astconv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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")
Expand All @@ -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");
Expand Down
4 changes: 3 additions & 1 deletion src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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, &[][..])
}
Expand Down
5 changes: 4 additions & 1 deletion src/test/compile-fail/issue-22560.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
}