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

Tests for issue 5997 failure and success conditions. #13525

Merged
merged 4 commits into from
Apr 18, 2014
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
10 changes: 6 additions & 4 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3507,8 +3507,9 @@ impl<'a> Resolver<'a> {
// its scope.

self.resolve_error(span,
"attempt to use a type \
argument out of scope");
"can't use type parameters from \
outer function; try using a local \
type parameter instead");
}

return None;
Expand All @@ -3530,8 +3531,9 @@ impl<'a> Resolver<'a> {
// its scope.

self.resolve_error(span,
"attempt to use a type \
argument out of scope");
"can't use type parameters from \
outer function; try using a local \
type parameter instead");
}

return None;
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,9 @@ impl<'a> TypeFolder for SubstFolder<'a> {
root.repr(self.tcx)),
None => ~""
};
let m = format!("missing type param `{}`{}",
t.repr(self.tcx), root_msg);
let m = format!("can't use type parameters from outer \
function{}; try using a local type \
parameter instead", root_msg);
match self.span {
Some(span) => self.tcx.sess.span_err(span, m),
None => self.tcx.sess.err(m)
Expand Down
22 changes: 12 additions & 10 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2416,13 +2416,13 @@ pub enum Representability {

/// Check whether a type is representable. This means it cannot contain unboxed
/// structural recursion. This check is needed for structs and enums.
pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
pub fn is_type_representable(cx: &ctxt, sp: Span, ty: t) -> Representability {

// Iterate until something non-representable is found
fn find_nonrepresentable<It: Iterator<t>>(cx: &ctxt, seen: &mut Vec<DefId>,
fn find_nonrepresentable<It: Iterator<t>>(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
mut iter: It) -> Representability {
for ty in iter {
let r = type_structurally_recursive(cx, seen, ty);
let r = type_structurally_recursive(cx, sp, seen, ty);
if r != Representable {
return r
}
Expand All @@ -2432,7 +2432,7 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {

// Does the type `ty` directly (without indirection through a pointer)
// contain any types on stack `seen`?
fn type_structurally_recursive(cx: &ctxt, seen: &mut Vec<DefId>,
fn type_structurally_recursive(cx: &ctxt, sp: Span, seen: &mut Vec<DefId>,
ty: t) -> Representability {
debug!("type_structurally_recursive: {}",
::util::ppaux::ty_to_str(cx, ty));
Expand All @@ -2455,19 +2455,19 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
match get(ty).sty {
// Tuples
ty_tup(ref ts) => {
find_nonrepresentable(cx, seen, ts.iter().map(|t| *t))
find_nonrepresentable(cx, sp, seen, ts.iter().map(|t| *t))
}
// Fixed-length vectors.
// FIXME(#11924) Behavior undecided for zero-length vectors.
ty_vec(ty, VstoreFixed(_)) => {
type_structurally_recursive(cx, seen, ty)
type_structurally_recursive(cx, sp, seen, ty)
}

// Push struct and enum def-ids onto `seen` before recursing.
ty_struct(did, ref substs) => {
seen.push(did);
let fields = struct_fields(cx, did, substs);
let r = find_nonrepresentable(cx, seen,
let r = find_nonrepresentable(cx, sp, seen,
fields.iter().map(|f| f.mt.ty));
seen.pop();
r
Expand All @@ -2478,8 +2478,10 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {

let mut r = Representable;
for variant in vs.iter() {
let iter = variant.args.iter().map(|aty| subst(cx, substs, *aty));
r = find_nonrepresentable(cx, seen, iter);
let iter = variant.args.iter().map(|aty| {
aty.subst_spanned(cx, substs, Some(sp))
});
r = find_nonrepresentable(cx, sp, seen, iter);

if r != Representable { break }
}
Expand All @@ -2499,7 +2501,7 @@ pub fn is_type_representable(cx: &ctxt, ty: t) -> Representability {
// contains a different, structurally recursive type, maintain a stack
// of seen types and check recursion for each of them (issues #3008, #3779).
let mut seen: Vec<DefId> = Vec::new();
type_structurally_recursive(cx, &mut seen, ty)
type_structurally_recursive(cx, sp, &mut seen, ty)
}

pub fn type_is_trait(ty: t) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3356,7 +3356,7 @@ pub fn check_representable(tcx: &ty::ctxt,
// recursive type. It is only necessary to throw an error on those that
// contain themselves. For case 2, there must be an inner type that will be
// caught by case 1.
match ty::is_type_representable(tcx, rty) {
match ty::is_type_representable(tcx, sp, rty) {
ty::SelfRecursive => {
tcx.sess.span_err(
sp, format!("illegal recursive {} type; \
Expand Down
19 changes: 18 additions & 1 deletion src/librustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,24 @@ pub fn ty_generics(ccx: &CrateCtxt,
let param_ty = ty::param_ty {idx: base_index + offset,
def_id: local_def(param.id)};
let bounds = @compute_bounds(ccx, param_ty, &param.bounds);
let default = param.default.map(|x| ast_ty_to_ty(ccx, &ExplicitRscope, x));
let default = param.default.map(|path| {
let ty = ast_ty_to_ty(ccx, &ExplicitRscope, path);
let cur_idx = param_ty.idx;

ty::walk_ty(ty, |t| {
match ty::get(t).sty {
ty::ty_param(p) => if p.idx > cur_idx {
ccx.tcx.sess.span_err(path.span,
"type parameters with a default cannot use \
forward declared identifiers")
},
_ => {}
}
});

ty
});

let def = ty::TypeParameterDef {
ident: param.ident,
def_id: local_def(param.id),
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/bad-type-env-capture.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
// except according to those terms.

fn foo<T>() {
fn bar(b: T) { } //~ ERROR attempt to use a type argument out of scope
fn bar(b: T) { } //~ ERROR can't use type parameters from outer
//~^ ERROR use of undeclared type name
}
fn main() { }
3 changes: 1 addition & 2 deletions src/test/compile-fail/generic-type-params-forward-mention.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@

// Ensure that we get an error and not an ICE for this problematic case.
struct Foo<T = Option<U>, U = bool>;

//~^ ERROR type parameters with a default cannot use forward declared identifiers
fn main() {
let x: Foo;
//~^ ERROR missing type param `U` in the substitution of `std::option::Option<U>`
}
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-3021-c.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
fn siphash<T>() {

trait t {
fn g(&self, x: T) -> T; //~ ERROR attempt to use a type argument out of scope
//~^ ERROR attempt to use a type argument out of scope
fn g(&self, x: T) -> T; //~ ERROR can't use type parameters from outer function; try using
//~^ ERROR can't use type parameters from outer function; try using
//~^^ ERROR use of undeclared type name `T`
//~^^^ ERROR use of undeclared type name `T`
}
Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/issue-3214.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

fn foo<T>() {
struct foo {
x: T, //~ ERROR attempt to use a type argument out of scope
x: T, //~ ERROR can't use type parameters from outer function;
//~^ ERROR use of undeclared type name
}

Expand Down
21 changes: 21 additions & 0 deletions src/test/compile-fail/issue-5997-enum.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2014 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.

fn f<Z>() -> bool {
enum E { V(Z) }
//~^ ERROR can't use type parameters from outer function in the

true
}

fn main() {
let b = f::<int>();
assert!(b);
}
21 changes: 21 additions & 0 deletions src/test/compile-fail/issue-5997-struct.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Copyright 2014 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.

fn f<T>() -> bool {
struct S(T); //~ ERROR use of undeclared type name `T`
//~^ ERROR can't use type parameters from outer function; try using

true
}

fn main() {
let b = f::<int>();
assert!(b);
}
2 changes: 1 addition & 1 deletion src/test/compile-fail/nested-ty-params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:attempt to use a type argument out of scope
// error-pattern:can't use type parameters from outer function; try using
fn hd<U>(v: Vec<U> ) -> U {
fn hd1(w: [U]) -> U { return w[0]; }

Expand Down
2 changes: 1 addition & 1 deletion src/test/compile-fail/type-arg-out-of-scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// error-pattern:attempt to use a type argument out of scope
// error-pattern:can't use type parameters from outer function; try using
fn foo<T>(x: T) {
fn bar(f: |T| -> T) { }
}
Expand Down
22 changes: 22 additions & 0 deletions src/test/run-pass/issue-5997.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2014 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.

fn f<T>() -> bool {
enum E<T> { V(T) }

struct S<T>(T);

true
}

fn main() {
let b = f::<int>();
assert!(b);
}