Skip to content

Commit 56d765d

Browse files
arielb1Ariel Ben-Yehuda
authored and
Ariel Ben-Yehuda
committed
Simplify and type_known_to_meet_builtin_bound and make it more correct when
associated types are involved.
1 parent 7a13b93 commit 56d765d

File tree

3 files changed

+62
-59
lines changed

3 files changed

+62
-59
lines changed

src/librustc/middle/traits/mod.rs

+16-59
Original file line numberDiff line numberDiff line change
@@ -304,12 +304,12 @@ pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
304304
/// `bound` or is not known to meet bound (note that this is
305305
/// conservative towards *no impl*, which is the opposite of the
306306
/// `evaluate` methods).
307-
pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
308-
typer: &ty::ClosureTyper<'tcx>,
309-
ty: Ty<'tcx>,
310-
bound: ty::BuiltinBound,
311-
span: Span)
312-
-> SelectionResult<'tcx, ()>
307+
pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
308+
typer: &ty::ClosureTyper<'tcx>,
309+
ty: Ty<'tcx>,
310+
bound: ty::BuiltinBound,
311+
span: Span)
312+
-> bool
313313
{
314314
debug!("type_known_to_meet_builtin_bound(ty={}, bound={:?})",
315315
ty.repr(infcx.tcx),
@@ -327,61 +327,18 @@ pub fn evaluate_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
327327
// Note: we only assume something is `Copy` if we can
328328
// *definitively* show that it implements `Copy`. Otherwise,
329329
// assume it is move; linear is always ok.
330-
let result = match fulfill_cx.select_all_or_error(infcx, typer) {
331-
Ok(()) => Ok(Some(())), // Success, we know it implements Copy.
332-
Err(errors) => {
333-
// If there were any hard errors, propagate an arbitrary
334-
// one of those. If no hard errors at all, report
335-
// ambiguity.
336-
let sel_error =
337-
errors.iter()
338-
.filter_map(|err| {
339-
match err.code {
340-
CodeAmbiguity => None,
341-
CodeSelectionError(ref e) => Some(e.clone()),
342-
CodeProjectionError(_) => {
343-
infcx.tcx.sess.span_bug(
344-
span,
345-
"projection error while selecting?")
346-
}
347-
}
348-
})
349-
.next();
350-
match sel_error {
351-
None => { Ok(None) }
352-
Some(e) => { Err(e) }
353-
}
354-
}
355-
};
356-
357-
debug!("type_known_to_meet_builtin_bound: ty={} bound={:?} result={:?}",
358-
ty.repr(infcx.tcx),
359-
bound,
360-
result);
361-
362-
result
363-
}
364-
365-
pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
366-
typer: &ty::ClosureTyper<'tcx>,
367-
ty: Ty<'tcx>,
368-
bound: ty::BuiltinBound,
369-
span: Span)
370-
-> bool
371-
{
372-
match evaluate_builtin_bound(infcx, typer, ty, bound, span) {
373-
Ok(Some(())) => {
374-
// definitely impl'd
330+
match fulfill_cx.select_all_or_error(infcx, typer) {
331+
Ok(()) => {
332+
debug!("type_known_to_meet_builtin_bound: ty={} bound={:?} success",
333+
ty.repr(infcx.tcx),
334+
bound);
375335
true
376336
}
377-
Ok(None) => {
378-
// ambiguous: if coherence check was successful, shouldn't
379-
// happen, but we might have reported an error and been
380-
// soldering on, so just treat this like not implemented
381-
false
382-
}
383-
Err(_) => {
384-
// errors: not implemented.
337+
Err(e) => {
338+
debug!("type_known_to_meet_builtin_bound: ty={} bound={:?} errors={}",
339+
ty.repr(infcx.tcx),
340+
bound,
341+
e.repr(infcx.tcx));
385342
false
386343
}
387344
}

src/test/compile-fail/issue-25700.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2015 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<T: 'static>(Option<&'static T>);
12+
13+
trait Tr { type Out; }
14+
impl<T> Tr for T { type Out = T; }
15+
16+
impl<T: 'static> Copy for S<T> where S<T>: Tr<Out=T> {}
17+
impl<T: 'static> Clone for S<T> where S<T>: Tr<Out=T> {
18+
fn clone(&self) -> Self { *self }
19+
}
20+
fn main() {
21+
let t = S::<()>(None);
22+
drop(t);
23+
drop(t); //~ ERROR use of moved value
24+
}

src/test/run-pass/issue-25700-1.rs

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright 2015 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<T: 'static>(Option<&'static T>);
12+
13+
trait Tr { type Out; }
14+
impl<T> Tr for T { type Out = T; }
15+
16+
impl<T: 'static> Copy for S<T> where S<T>: Tr<Out=T> {}
17+
impl<T: 'static> Clone for S<T> where S<T>: Tr<Out=T> {
18+
fn clone(&self) -> Self { *self }
19+
}
20+
fn main() {
21+
S::<()>(None);
22+
}

0 commit comments

Comments
 (0)