Skip to content

Commit

Permalink
Fix off-by-one error in default-type-parameter checking
Browse files Browse the repository at this point in the history
Fixes #18183
  • Loading branch information
Ariel Ben-Yehuda committed Jun 29, 2015
1 parent 40db46c commit a1110bc
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 19 deletions.
45 changes: 26 additions & 19 deletions src/librustc_typeck/collect.rs
Expand Up @@ -1860,6 +1860,29 @@ fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
result
}

fn convert_default_type_parameter<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
path: &P<ast::Ty>,
space: ParamSpace,
index: u32)
-> Ty<'tcx>
{
let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &path);

for leaf_ty in ty.walk() {
if let ty::TyParam(p) = leaf_ty.sty {
if p.space == space && p.idx >= index {
span_err!(ccx.tcx.sess, path.span, E0128,
"type parameters with a default cannot use \
forward declared identifiers");

return ccx.tcx.types.err
}
}
}

ty
}

fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
ast_generics: &ast::Generics,
space: ParamSpace,
Expand All @@ -1874,25 +1897,9 @@ fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
None => { }
}

let default = match param.default {
None => None,
Some(ref path) => {
let ty = ast_ty_to_ty(&ccx.icx(&()), &ExplicitRscope, &**path);
let cur_idx = index;

for leaf_ty in ty.walk() {
if let ty::TyParam(p) = leaf_ty.sty {
if p.idx > cur_idx {
span_err!(tcx.sess, path.span, E0128,
"type parameters with a default cannot use \
forward declared identifiers");
}
}
}

Some(ty)
}
};
let default = param.default.as_ref().map(
|def| convert_default_type_parameter(ccx, def, space, index)
);

let object_lifetime_default =
compute_object_lifetime_default(ccx, param.id,
Expand Down
13 changes: 13 additions & 0 deletions src/test/compile-fail/issue-18183.rs
@@ -0,0 +1,13 @@
// Copyright 2015 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.

pub struct Foo<Bar=Bar>; //~ ERROR E0128
pub struct Baz(Foo);
fn main() {}

0 comments on commit a1110bc

Please sign in to comment.