Skip to content

Commit 462c83e

Browse files
committedMar 14, 2016
Address basic nits from initial review
1 parent 9734406 commit 462c83e

File tree

7 files changed

+97
-19
lines changed

7 files changed

+97
-19
lines changed
 

‎src/librustc/middle/traits/specialize.rs

+9-8
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,9 @@ pub struct SpecializationGraph {
5252
}
5353

5454
/// Information pertinent to an overlapping impl error.
55-
pub struct Overlap<'tcx> {
55+
pub struct Overlap<'a, 'tcx: 'a> {
56+
pub in_context: InferCtxt<'a, 'tcx>,
5657
pub with_impl: DefId,
57-
58-
/// NB: this TraitRef can contain inference variables!
5958
pub on_trait_ref: ty::TraitRef<'tcx>,
6059
}
6160

@@ -70,13 +69,13 @@ impl SpecializationGraph {
7069
/// Insert a local impl into the specialization graph. If an existing impl
7170
/// conflicts with it (has overlap, but neither specializes the other),
7271
/// information about the area of overlap is returned in the `Err`.
73-
pub fn insert<'tcx>(&mut self,
74-
tcx: &ty::ctxt<'tcx>,
75-
impl_def_id: DefId,
76-
trait_ref: ty::TraitRef)
77-
-> Result<(), Overlap<'tcx>> {
72+
pub fn insert<'a, 'tcx>(&mut self,
73+
tcx: &'a ty::ctxt<'tcx>,
74+
impl_def_id: DefId)
75+
-> Result<(), Overlap<'a, 'tcx>> {
7876
assert!(impl_def_id.is_local());
7977

78+
let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
8079
let mut parent = trait_ref.def_id;
8180
let mut my_children = vec![];
8281

@@ -98,6 +97,7 @@ impl SpecializationGraph {
9897
return Err(Overlap {
9998
with_impl: possible_sibling,
10099
on_trait_ref: trait_ref,
100+
in_context: infcx,
101101
});
102102
}
103103

@@ -118,6 +118,7 @@ impl SpecializationGraph {
118118
return Err(Overlap {
119119
with_impl: possible_sibling,
120120
on_trait_ref: trait_ref,
121+
in_context: infcx,
121122
});
122123
}
123124

‎src/librustc/middle/ty/trait_def.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ impl<'tcx> TraitDef<'tcx> {
125125
fn record_impl(&self,
126126
tcx: &TyCtxt<'tcx>,
127127
impl_def_id: DefId,
128-
impl_trait_ref: TraitRef<'tcx>) -> bool {
128+
impl_trait_ref: TraitRef<'tcx>)
129+
-> bool {
129130
debug!("TraitDef::record_impl for {:?}, from {:?}",
130131
self, impl_trait_ref);
131132

@@ -161,7 +162,9 @@ impl<'tcx> TraitDef<'tcx> {
161162
tcx: &TyCtxt<'tcx>,
162163
impl_def_id: DefId,
163164
impl_trait_ref: TraitRef<'tcx>) {
164-
self.record_impl(tcx, impl_def_id, impl_trait_ref);
165+
assert!(impl_def_id.is_local());
166+
let was_new = self.record_impl(tcx, impl_def_id, impl_trait_ref);
167+
assert!(was_new);
165168
}
166169

167170
/// Records a trait-to-implementation mapping for a non-local impl.
@@ -174,6 +177,8 @@ impl<'tcx> TraitDef<'tcx> {
174177
impl_def_id: DefId,
175178
impl_trait_ref: TraitRef<'tcx>,
176179
parent_impl: DefId) {
180+
assert!(!impl_def_id.is_local());
181+
177182
// if the impl has not previously been recorded
178183
if self.record_impl(tcx, impl_def_id, impl_trait_ref) {
179184
// if the impl is non-local, it's placed directly into the
@@ -186,15 +191,14 @@ impl<'tcx> TraitDef<'tcx> {
186191
/// Adds a local impl into the specialization graph, returning an error with
187192
/// overlap information if the impl overlaps but does not specialize an
188193
/// existing impl.
189-
pub fn add_impl_for_specialization(&self,
190-
tcx: &ctxt<'tcx>,
191-
impl_def_id: DefId,
192-
impl_trait_ref: TraitRef<'tcx>)
193-
-> Result<(), traits::Overlap<'tcx>> {
194+
pub fn add_impl_for_specialization<'a>(&self,
195+
tcx: &'a ctxt<'tcx>,
196+
impl_def_id: DefId)
197+
-> Result<(), traits::Overlap<'a, 'tcx>> {
194198
assert!(impl_def_id.is_local());
195199

196200
self.specialization_graph.borrow_mut()
197-
.insert(tcx, impl_def_id, impl_trait_ref)
201+
.insert(tcx, impl_def_id)
198202
}
199203

200204
/// Returns the immediately less specialized impl, if any.

‎src/librustc_typeck/coherence/overlap.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,7 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
133133
let def = self.tcx.lookup_trait_def(trait_def_id);
134134

135135
// attempt to insert into the specialization graph
136-
let insert_result = def.add_impl_for_specialization(self.tcx,
137-
impl_def_id,
138-
trait_ref);
136+
let insert_result = def.add_impl_for_specialization(self.tcx, impl_def_id);
139137

140138
// insertion failed due to overlap
141139
if let Err(overlap) = insert_result {

‎src/libsyntax/feature_gate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Option<u32>, Status
250250
("question_mark", "1.9.0", Some(31436), Active)
251251

252252
// impl specialization (RFC 1210)
253+
// TODO: update with issue number (once it exists), before landing
253254
("specialization", "1.7.0", None, Active),
254255
];
255256
// (changing above list without updating src/doc/reference.md makes @cmr sad)

‎src/test/compile-fail/specialization-negative-impl.rs

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313

1414
struct TestType<T>(T);
1515

16+
// TODO: nail down the rules here with @nikomatsakis
17+
1618
unsafe impl<T> Send for TestType<T> {}
1719
impl !Send for TestType<u8> {}
1820

‎src/test/compile-fail/specialization-no-default.rs

+49
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010

1111
#![feature(specialization)]
1212

13+
////////////////////////////////////////////////////////////////////////////////
14+
// Test 1: one layer of specialization, multiple methods, missing `default`
15+
////////////////////////////////////////////////////////////////////////////////
16+
1317
trait Foo {
1418
fn foo(&self);
1519
fn bar(&self);
@@ -28,6 +32,10 @@ impl Foo for u32 {
2832
fn bar(&self) {} //~ ERROR E0520
2933
}
3034

35+
////////////////////////////////////////////////////////////////////////////////
36+
// Test 2: one layer of specialization, missing `default` on associated type
37+
////////////////////////////////////////////////////////////////////////////////
38+
3139
trait Bar {
3240
type T;
3341
}
@@ -40,4 +48,45 @@ impl Bar for u8 {
4048
type T = (); //~ ERROR E0520
4149
}
4250

51+
////////////////////////////////////////////////////////////////////////////////
52+
// Test 3a: multiple layers of specialization, missing interior `default`
53+
////////////////////////////////////////////////////////////////////////////////
54+
55+
trait Baz {
56+
fn baz(&self);
57+
}
58+
59+
impl<T> Baz for T {
60+
default fn baz(&self) {}
61+
}
62+
63+
impl<T: Clone> Baz for T {
64+
fn baz(&self) {}
65+
}
66+
67+
impl Baz for i32 {
68+
fn baz(&self) {}
69+
}
70+
71+
////////////////////////////////////////////////////////////////////////////////
72+
// Test 3b: multiple layers of specialization, missing interior `default`,
73+
// redundant `default` in bottom layer.
74+
////////////////////////////////////////////////////////////////////////////////
75+
76+
trait Redundant {
77+
fn redundant(&self);
78+
}
79+
80+
impl<T> Redundant for T {
81+
default fn redundant(&self) {}
82+
}
83+
84+
impl<T: Clone> Redundant for T {
85+
fn redundant(&self) {}
86+
}
87+
88+
impl Redundant for i32 {
89+
default fn redundant(&self) {}
90+
}
91+
4392
fn main() {}

‎src/test/run-pass/specialization-default-methods.rs

+23
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ trait Foo {
1616
fn foo(&self) -> bool;
1717
}
1818

19+
// Specialization tree for Foo:
20+
//
21+
// T
22+
// / \
23+
// i32 i64
24+
1925
impl<T> Foo for T {
2026
default fn foo(&self) -> bool { false }
2127
}
@@ -38,6 +44,23 @@ trait Bar {
3844
fn bar(&self) -> i32 { 0 }
3945
}
4046

47+
// Specialization tree for Bar.
48+
// Uses of $ designate that method is provided
49+
//
50+
// $Bar (the trait)
51+
// |
52+
// T
53+
// /|\
54+
// / | \
55+
// / | \
56+
// / | \
57+
// / | \
58+
// / | \
59+
// $i32 &str $Vec<T>
60+
// /\
61+
// / \
62+
// Vec<i32> $Vec<i64>
63+
4164
impl<T> Bar for T {} // use the provided method
4265

4366
impl Bar for i32 {

0 commit comments

Comments
 (0)
Please sign in to comment.