Skip to content

Commit eada951

Browse files
committed
Support Self in struct expressions and patterns
1 parent a9f91b1 commit eada951

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed

src/librustc_typeck/check/mod.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -3234,16 +3234,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
32343234
}
32353235
}
32363236
Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
3237-
Def::AssociatedTy(..) => {
3237+
Def::AssociatedTy(..) | Def::SelfTy(..) => {
32383238
match ty.sty {
32393239
ty::TyAdt(adt, substs) if !adt.is_enum() => {
32403240
Some((adt.struct_variant(), adt.did, substs))
32413241
}
32423242
_ => None,
32433243
}
32443244
}
3245-
// Self is not supported yet.
3246-
Def::SelfTy(..) => None,
32473245
_ => bug!("unexpected definition: {:?}", def)
32483246
};
32493247

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2016 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+
struct S;
12+
13+
trait Tr {
14+
fn f() {
15+
let s = Self {};
16+
//~^ ERROR expected struct, variant or union type, found type parameter `Self`
17+
let z = Self::<u8> {};
18+
//~^ ERROR expected struct, variant or union type, found type parameter `Self`
19+
//~| ERROR type parameters are not allowed on this type
20+
match s {
21+
Self { .. } => {}
22+
//~^ ERROR expected struct, variant or union type, found type parameter `Self`
23+
}
24+
}
25+
}
26+
27+
impl Tr for S {
28+
fn f() {
29+
let s = Self {}; // OK
30+
let z = Self::<u8> {}; //~ ERROR type parameters are not allowed on this type
31+
match s {
32+
Self { .. } => {} // OK
33+
}
34+
}
35+
}
36+
37+
impl S {
38+
fn g() {
39+
let s = Self {}; // OK
40+
let z = Self::<u8> {}; //~ ERROR type parameters are not allowed on this type
41+
match s {
42+
Self { .. } => {} // OK
43+
}
44+
}
45+
}
46+
47+
fn main() {}

src/test/run-pass/struct-path-self.rs

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
// Copyright 2016 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+
use std::ops::Add;
12+
13+
struct S<T, U = u16> {
14+
a: T,
15+
b: U,
16+
}
17+
18+
trait Tr {
19+
fn f(&self) -> Self;
20+
}
21+
22+
impl<T: Default + Add<u8, Output = T>, U: Default> Tr for S<T, U> {
23+
fn f(&self) -> Self {
24+
let s = Self { a: Default::default(), b: Default::default() };
25+
match s {
26+
Self { a, b } => Self { a: a + 1, b: b }
27+
}
28+
}
29+
}
30+
31+
impl<T: Default, U: Default + Add<u16, Output = U>> S<T, U> {
32+
fn g(&self) -> Self {
33+
let s = Self { a: Default::default(), b: Default::default() };
34+
match s {
35+
Self { a, b } => Self { a: a, b: b + 1 }
36+
}
37+
}
38+
}
39+
40+
impl S<u8> {
41+
fn new() -> Self {
42+
Self { a: 0, b: 1 }
43+
}
44+
}
45+
46+
fn main() {
47+
let s0 = S::new();
48+
let s1 = s0.f();
49+
assert_eq!(s1.a, 1);
50+
assert_eq!(s1.b, 0);
51+
let s2 = s0.g();
52+
assert_eq!(s2.a, 0);
53+
assert_eq!(s2.b, 1);
54+
}

0 commit comments

Comments
 (0)