Skip to content

Commit 4d6dc7f

Browse files
committed
Auto merge of #28396 - arielb1:misplaced-binding, r=eddyb
Technically a [breaking-change], but the broken code is useless, like `i32<Param=()>`. Fixes #24682 r? @eddyb
2 parents 009f2cf + 5d44555 commit 4d6dc7f

File tree

6 files changed

+66
-33
lines changed

6 files changed

+66
-33
lines changed

src/librustc/diagnostics.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1895,6 +1895,7 @@ register_diagnostics! {
18951895
// E0006 // merged with E0005
18961896
// E0134,
18971897
// E0135,
1898+
E0229, // associated type bindings are not allowed here
18981899
E0264, // unknown external lang item
18991900
E0278, // requirement is not satisfied
19001901
E0279, // requirement is not satisfied

src/librustc/middle/astconv_util.rs

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -16,36 +16,40 @@
1616

1717
use middle::def;
1818
use middle::ty::{self, Ty};
19-
use rustc_front::hir as ast;
2019

21-
pub const NO_REGIONS: usize = 1;
22-
pub const NO_TPS: usize = 2;
20+
use syntax::codemap::Span;
21+
use rustc_front::hir as ast;
2322

24-
pub fn check_path_args(tcx: &ty::ctxt, segments: &[ast::PathSegment], flags: usize) {
23+
pub fn prohibit_type_params(tcx: &ty::ctxt, segments: &[ast::PathSegment]) {
2524
for segment in segments {
26-
if (flags & NO_TPS) != 0 {
27-
for typ in segment.parameters.types() {
28-
span_err!(tcx.sess, typ.span, E0109,
29-
"type parameters are not allowed on this type");
30-
break;
31-
}
25+
for typ in segment.parameters.types() {
26+
span_err!(tcx.sess, typ.span, E0109,
27+
"type parameters are not allowed on this type");
28+
break;
3229
}
33-
34-
if (flags & NO_REGIONS) != 0 {
35-
for lifetime in segment.parameters.lifetimes() {
36-
span_err!(tcx.sess, lifetime.span, E0110,
37-
"lifetime parameters are not allowed on this type");
38-
break;
39-
}
30+
for lifetime in segment.parameters.lifetimes() {
31+
span_err!(tcx.sess, lifetime.span, E0110,
32+
"lifetime parameters are not allowed on this type");
33+
break;
34+
}
35+
for binding in segment.parameters.bindings() {
36+
prohibit_projection(tcx, binding.span);
37+
break;
4038
}
4139
}
4240
}
4341

42+
pub fn prohibit_projection(tcx: &ty::ctxt, span: Span)
43+
{
44+
span_err!(tcx.sess, span, E0229,
45+
"associated type bindings are not allowed here");
46+
}
47+
4448
pub fn prim_ty_to_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
4549
segments: &[ast::PathSegment],
4650
nty: ast::PrimTy)
4751
-> Ty<'tcx> {
48-
check_path_args(tcx, segments, NO_TPS | NO_REGIONS);
52+
prohibit_type_params(tcx, segments);
4953
match nty {
5054
ast::TyBool => tcx.types.bool,
5155
ast::TyChar => tcx.types.char,

src/librustc_typeck/astconv.rs

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
//! case but `&a` in the second. Basically, defaults that appear inside
4949
//! an rptr (`&r.T`) use the region `r` that appears in the rptr.
5050
51-
use middle::astconv_util::{prim_ty_to_ty, check_path_args, NO_TPS, NO_REGIONS};
51+
use middle::astconv_util::{prim_ty_to_ty, prohibit_type_params, prohibit_projection};
5252
use middle::const_eval::{self, ConstVal};
5353
use middle::const_eval::EvalHint::UncheckedExprHint;
5454
use middle::def;
@@ -1210,7 +1210,7 @@ fn associated_path_def_to_ty<'tcx>(this: &AstConv<'tcx>,
12101210

12111211
debug!("associated_path_def_to_ty: {:?}::{}", ty, assoc_name);
12121212

1213-
check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
1213+
prohibit_type_params(tcx, slice::ref_slice(item_segment));
12141214

12151215
// Find the type of the associated item, and the trait where the associated
12161216
// item is declared.
@@ -1312,7 +1312,7 @@ fn qpath_to_ty<'tcx>(this: &AstConv<'tcx>,
13121312
{
13131313
let tcx = this.tcx();
13141314

1315-
check_path_args(tcx, slice::ref_slice(item_segment), NO_TPS | NO_REGIONS);
1315+
prohibit_type_params(tcx, slice::ref_slice(item_segment));
13161316

13171317
let self_ty = if let Some(ty) = opt_self_ty {
13181318
ty
@@ -1401,7 +1401,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
14011401
base_segments.last().unwrap(),
14021402
&mut projection_bounds);
14031403

1404-
check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS);
1404+
prohibit_type_params(tcx, base_segments.split_last().unwrap().1);
14051405
trait_ref_to_object_type(this,
14061406
rscope,
14071407
span,
@@ -1410,7 +1410,7 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
14101410
&[])
14111411
}
14121412
def::DefTy(did, _) | def::DefStruct(did) => {
1413-
check_path_args(tcx, base_segments.split_last().unwrap().1, NO_TPS | NO_REGIONS);
1413+
prohibit_type_params(tcx, base_segments.split_last().unwrap().1);
14141414
ast_path_to_ty(this,
14151415
rscope,
14161416
span,
@@ -1419,12 +1419,12 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
14191419
base_segments.last().unwrap())
14201420
}
14211421
def::DefTyParam(space, index, _, name) => {
1422-
check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
1422+
prohibit_type_params(tcx, base_segments);
14231423
tcx.mk_param(space, index, name)
14241424
}
14251425
def::DefSelfTy(_, Some((_, self_ty_id))) => {
14261426
// Self in impl (we know the concrete type).
1427-
check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
1427+
prohibit_type_params(tcx, base_segments);
14281428
if let Some(&ty) = tcx.ast_ty_to_ty_cache.borrow().get(&self_ty_id) {
14291429
if let Some(free_substs) = this.get_free_substs() {
14301430
ty.subst(tcx, free_substs)
@@ -1437,11 +1437,11 @@ fn base_def_to_ty<'tcx>(this: &AstConv<'tcx>,
14371437
}
14381438
def::DefSelfTy(Some(_), None) => {
14391439
// Self in trait.
1440-
check_path_args(tcx, base_segments, NO_TPS | NO_REGIONS);
1440+
prohibit_type_params(tcx, base_segments);
14411441
tcx.mk_self_type()
14421442
}
14431443
def::DefAssociatedTy(trait_did, _) => {
1444-
check_path_args(tcx, &base_segments[..base_segments.len()-2], NO_TPS | NO_REGIONS);
1444+
prohibit_type_params(tcx, &base_segments[..base_segments.len()-2]);
14451445
qpath_to_ty(this,
14461446
rscope,
14471447
span,
@@ -2185,8 +2185,7 @@ fn prohibit_projections<'tcx>(tcx: &ty::ctxt<'tcx>,
21852185
bindings: &[ConvertedBinding<'tcx>])
21862186
{
21872187
for binding in bindings.iter().take(1) {
2188-
span_err!(tcx.sess, binding.span, E0229,
2189-
"associated type bindings are not allowed here");
2188+
prohibit_projection(tcx, binding.span);
21902189
}
21912190
}
21922191

src/librustc_typeck/check/mod.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ use self::TupleArgumentsFlag::*;
8383
use astconv::{self, ast_region_to_region, ast_ty_to_ty, AstConv, PathParamMode};
8484
use check::_match::pat_ctxt;
8585
use fmt_macros::{Parser, Piece, Position};
86-
use middle::astconv_util::{check_path_args, NO_TPS, NO_REGIONS};
86+
use middle::astconv_util::prohibit_type_params;
8787
use middle::def;
8888
use middle::def_id::{DefId, LOCAL_CRATE};
8989
use middle::infer;
@@ -4535,8 +4535,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
45354535
for (opt_space, segment) in segment_spaces.iter().zip(segments) {
45364536
match *opt_space {
45374537
None => {
4538-
check_path_args(fcx.tcx(), slice::ref_slice(segment),
4539-
NO_TPS | NO_REGIONS);
4538+
prohibit_type_params(fcx.tcx(), slice::ref_slice(segment));
45404539
}
45414540

45424541
Some(space) => {

src/librustc_typeck/diagnostics.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3294,7 +3294,6 @@ register_diagnostics! {
32943294
E0226, // only a single explicit lifetime bound is permitted
32953295
E0227, // ambiguous lifetime bound, explicit lifetime bound required
32963296
E0228, // explicit lifetime bound required
3297-
E0229, // associated type bindings are not allowed here
32983297
E0230, // there is no type parameter on trait
32993298
E0231, // only named substitution parameters are allowed
33003299
// E0233,

src/test/compile-fail/issue-24682.rs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
trait A: Sized {
12+
type N;
13+
fn x() ->
14+
Self<
15+
N= //~ ERROR associated type bindings are not allowed here
16+
Self::N> {
17+
loop {}
18+
}
19+
fn y(&self) ->
20+
std
21+
<N=()> //~ ERROR associated type bindings are not allowed here
22+
::option::Option<()>
23+
{ None }
24+
fn z(&self) ->
25+
u32<N=()> //~ ERROR associated type bindings are not allowed here
26+
{ 42 }
27+
28+
}
29+
30+
fn main() {
31+
}

0 commit comments

Comments
 (0)