1
Fork 0

Fix off-by-one error in default-type-parameter checking

Fixes #18183
This commit is contained in:
Ariel Ben-Yehuda 2015-06-29 21:07:09 +03:00
parent 40db46c6ba
commit a1110bc3a3
2 changed files with 39 additions and 19 deletions

View file

@ -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,
@ -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,

View file

@ -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() {}