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

Allow bounds on type variables in enums & structs #13302

Closed
wants to merge 1 commit into from
Closed
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
5 changes: 3 additions & 2 deletions src/librustc/middle/resolve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3602,7 +3602,8 @@ impl<'a> Resolver<'a> {
0,
NormalRibKind),
|this| {
visit::walk_item(this, item, ());
this.resolve_type_parameters(&generics.ty_params);
visit::walk_enum_def(this, enum_def, generics, ());
});
}

Expand Down Expand Up @@ -3859,7 +3860,7 @@ impl<'a> Resolver<'a> {
}

fn resolve_type_parameters(&mut self,
type_parameters: &OwnedSlice<TyParam>) {
type_parameters: &OwnedSlice<TyParam>) {
for type_parameter in type_parameters.iter() {
for bound in type_parameter.bounds.iter() {
self.resolve_type_parameter_bound(type_parameter.id, bound);
Expand Down
12 changes: 5 additions & 7 deletions src/librustc/middle/typeck/collect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,9 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
// These don't define types.
ast::ItemForeignMod(_) | ast::ItemMod(_) | ast::ItemMac(_) => {}
ast::ItemEnum(ref enum_definition, ref generics) => {
ensure_no_ty_param_bounds(ccx, it.span, generics, "enumeration");
let tpt = ty_of_item(ccx, it);
write_ty_to_tcx(tcx, it.id, tpt.ty);
tcx.tcache.borrow_mut().insert(local_def(it.id), tpt.clone());
get_enum_variant_types(ccx,
tpt.ty,
enum_definition.variants.as_slice(),
Expand All @@ -580,9 +580,9 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
write_ty_to_tcx(tcx, it.id, selfty);

tcx.tcache.borrow_mut().insert(local_def(it.id),
ty_param_bounds_and_ty {
generics: ty_generics.clone(),
ty: selfty});
ty_param_bounds_and_ty {
generics: ty_generics.clone(),
ty: selfty});

// If there is a trait reference, treat the methods as always public.
// This is to work around some incorrect behavior in privacy checking:
Expand Down Expand Up @@ -634,9 +634,7 @@ pub fn convert(ccx: &CrateCtxt, it: &ast::Item) {
// static trait methods. This is somewhat unfortunate.
ensure_trait_methods(ccx, it.id);
},
ast::ItemStruct(struct_def, ref generics) => {
ensure_no_ty_param_bounds(ccx, it.span, generics, "structure");

ast::ItemStruct(struct_def, _) => {
// Write the class type
let tpt = ty_of_item(ccx, it);
write_ty_to_tcx(tcx, it.id, tpt.ty);
Expand Down
21 changes: 21 additions & 0 deletions src/test/compile-fail/struct-enum-bounds-1.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.

// Test that incorrect bounds in structs and enums are picked up.

struct Foo<X: T>; //~ERROR attempt to bound type parameter with a nonexistent trait `T`
enum Bar<X: T> {} //~ERROR attempt to bound type parameter with a nonexistent trait `T`

trait T2<X> {}

struct Baz<X: T2<T>>; //~ ERROR use of undeclared type name `T`
enum Qux<X: T2<T>> {} //~ ERROR use of undeclared type name `T`

fn main() {}
18 changes: 18 additions & 0 deletions src/test/compile-fail/struct-enum-bounds-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// 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.

// Test that incorrect bounds in structs and enums are picked up.

trait T<'a> {}

struct Baz2<X: T<'a>>; //~ERROR use of undeclared lifetime name `'a`
enum Quz2<X: T<'a>> {} //~ERROR use of undeclared lifetime name `'a`

fn main() {}
27 changes: 27 additions & 0 deletions src/test/run-pass/struct-enum-bounds.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// 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.

// Test that bounds are allowed on structs and enums.

trait T {}

struct S<X: T>;

enum E<X: T> {
}

impl<X: T> S<X> {}
impl<X: T> E<X> {}

trait T2<'a> {}

struct S2<'a, X: T2<'a>>;

fn main() {}