Skip to content

Commit a45e117

Browse files
committed
Auto merge of #21019 - nikomatsakis:issue-20871-ret-as-assoc-type, r=nrc
Fixes #20871 r? @aturon (at least until we decide definitively if this is a good idea)
2 parents 06410ef + 05ffdc5 commit a45e117

File tree

76 files changed

+1098
-482
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+1098
-482
lines changed

src/libcollections/btree/set.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,9 @@ mod test {
758758
expected: &'b [int],
759759
}
760760

761-
impl<'a, 'b, 'c> FnMut(&'c int) -> bool for Counter<'a, 'b> {
761+
impl<'a, 'b, 'c> FnMut<(&'c int,)> for Counter<'a, 'b> {
762+
type Output = bool;
763+
762764
extern "rust-call" fn call_mut(&mut self, (&x,): (&'c int,)) -> bool {
763765
assert_eq!(x, self.expected[*self.i]);
764766
*self.i += 1;

src/libcore/ops.rs

+69-6
Original file line numberDiff line numberDiff line change
@@ -1117,29 +1117,33 @@ impl<'a, T: ?Sized> DerefMut for &'a mut T {
11171117
#[lang="fn"]
11181118
#[unstable(feature = "core",
11191119
reason = "uncertain about variadic generics, input versus associated types")]
1120-
pub trait Fn<Args,Result> {
1120+
#[cfg(stage0)]
1121+
pub trait Fn<Args,Output> {
11211122
/// This is called when the call operator is used.
1122-
extern "rust-call" fn call(&self, args: Args) -> Result;
1123+
extern "rust-call" fn call(&self, args: Args) -> Output;
11231124
}
11241125

11251126
/// A version of the call operator that takes a mutable receiver.
11261127
#[lang="fn_mut"]
11271128
#[unstable(feature = "core",
11281129
reason = "uncertain about variadic generics, input versus associated types")]
1129-
pub trait FnMut<Args,Result> {
1130+
#[cfg(stage0)]
1131+
pub trait FnMut<Args,Output> {
11301132
/// This is called when the call operator is used.
1131-
extern "rust-call" fn call_mut(&mut self, args: Args) -> Result;
1133+
extern "rust-call" fn call_mut(&mut self, args: Args) -> Output;
11321134
}
11331135

11341136
/// A version of the call operator that takes a by-value receiver.
11351137
#[lang="fn_once"]
11361138
#[unstable(feature = "core",
11371139
reason = "uncertain about variadic generics, input versus associated types")]
1138-
pub trait FnOnce<Args,Result> {
1140+
#[cfg(stage0)]
1141+
pub trait FnOnce<Args,Output> {
11391142
/// This is called when the call operator is used.
1140-
extern "rust-call" fn call_once(self, args: Args) -> Result;
1143+
extern "rust-call" fn call_once(self, args: Args) -> Output;
11411144
}
11421145

1146+
#[cfg(stage0)]
11431147
impl<F: ?Sized, A, R> FnMut<A, R> for F
11441148
where F : Fn<A, R>
11451149
{
@@ -1148,10 +1152,69 @@ impl<F: ?Sized, A, R> FnMut<A, R> for F
11481152
}
11491153
}
11501154

1155+
#[cfg(stage0)]
11511156
impl<F,A,R> FnOnce<A,R> for F
11521157
where F : FnMut<A,R>
11531158
{
11541159
extern "rust-call" fn call_once(mut self, args: A) -> R {
11551160
self.call_mut(args)
11561161
}
11571162
}
1163+
1164+
/// A version of the call operator that takes an immutable receiver.
1165+
#[lang="fn"]
1166+
#[unstable(feature = "core",
1167+
reason = "uncertain about variadic generics, input versus associated types")]
1168+
#[cfg(not(stage0))]
1169+
pub trait Fn<Args> {
1170+
type Output;
1171+
1172+
/// This is called when the call operator is used.
1173+
extern "rust-call" fn call(&self, args: Args) -> Self::Output;
1174+
}
1175+
1176+
/// A version of the call operator that takes a mutable receiver.
1177+
#[lang="fn_mut"]
1178+
#[unstable(feature = "core",
1179+
reason = "uncertain about variadic generics, input versus associated types")]
1180+
#[cfg(not(stage0))]
1181+
pub trait FnMut<Args> {
1182+
type Output;
1183+
1184+
/// This is called when the call operator is used.
1185+
extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output;
1186+
}
1187+
1188+
/// A version of the call operator that takes a by-value receiver.
1189+
#[lang="fn_once"]
1190+
#[unstable(feature = "core",
1191+
reason = "uncertain about variadic generics, input versus associated types")]
1192+
#[cfg(not(stage0))]
1193+
pub trait FnOnce<Args> {
1194+
type Output;
1195+
1196+
/// This is called when the call operator is used.
1197+
extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
1198+
}
1199+
1200+
#[cfg(not(stage0))]
1201+
impl<F: ?Sized, A> FnMut<A> for F
1202+
where F : Fn<A>
1203+
{
1204+
type Output = <F as Fn<A>>::Output;
1205+
1206+
extern "rust-call" fn call_mut(&mut self, args: A) -> <F as Fn<A>>::Output {
1207+
self.call(args)
1208+
}
1209+
}
1210+
1211+
#[cfg(not(stage0))]
1212+
impl<F,A> FnOnce<A> for F
1213+
where F : FnMut<A>
1214+
{
1215+
type Output = <F as FnMut<A>>::Output;
1216+
1217+
extern "rust-call" fn call_once(mut self, args: A) -> <F as FnMut<A>>::Output {
1218+
self.call_mut(args)
1219+
}
1220+
}

src/libcore/str/mod.rs

+11
Original file line numberDiff line numberDiff line change
@@ -461,13 +461,24 @@ delegate_iter!{exact u8 : Bytes<'a>}
461461
#[derive(Copy, Clone)]
462462
struct BytesDeref;
463463

464+
#[cfg(stage0)]
464465
impl<'a> Fn(&'a u8) -> u8 for BytesDeref {
465466
#[inline]
466467
extern "rust-call" fn call(&self, (ptr,): (&'a u8,)) -> u8 {
467468
*ptr
468469
}
469470
}
470471

472+
#[cfg(not(stage0))]
473+
impl<'a> Fn<(&'a u8,)> for BytesDeref {
474+
type Output = u8;
475+
476+
#[inline]
477+
extern "rust-call" fn call(&self, (ptr,): (&'a u8,)) -> u8 {
478+
*ptr
479+
}
480+
}
481+
471482
/// An iterator over the substrings of a string, separated by `sep`.
472483
#[derive(Clone)]
473484
struct CharSplits<'a, Sep> {

src/librustc/middle/astencode.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -904,8 +904,8 @@ impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
904904
try!(this.emit_struct_field("method_num", 0, |this| {
905905
this.emit_uint(o.method_num)
906906
}));
907-
try!(this.emit_struct_field("real_index", 0, |this| {
908-
this.emit_uint(o.real_index)
907+
try!(this.emit_struct_field("vtable_index", 0, |this| {
908+
this.emit_uint(o.vtable_index)
909909
}));
910910
Ok(())
911911
})
@@ -1492,8 +1492,8 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
14921492
this.read_uint()
14931493
}).unwrap()
14941494
},
1495-
real_index: {
1496-
this.read_struct_field("real_index", 3, |this| {
1495+
vtable_index: {
1496+
this.read_struct_field("vtable_index", 3, |this| {
14971497
this.read_uint()
14981498
}).unwrap()
14991499
},

src/librustc/middle/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -408,7 +408,7 @@ fn note_obligation_cause_code<'a, 'tcx>(infcx: &InferCtxt<'a, 'tcx>,
408408
}
409409
ObligationCauseCode::CompareImplMethodObligation => {
410410
span_note!(tcx.sess, cause_span,
411-
"the requirement `{}` appears on the impl method\
411+
"the requirement `{}` appears on the impl method \
412412
but not on the corresponding trait method",
413413
predicate.user_string(infcx.tcx));
414414
}

src/librustc/middle/traits/mod.rs

+60-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ pub use self::ObligationCauseCode::*;
1818
use middle::mem_categorization::Typer;
1919
use middle::subst;
2020
use middle::ty::{self, Ty};
21-
use middle::infer::InferCtxt;
21+
use middle::infer::{self, InferCtxt};
2222
use std::slice::Iter;
2323
use std::rc::Rc;
2424
use syntax::ast;
@@ -392,6 +392,65 @@ pub fn type_known_to_meet_builtin_bound<'a,'tcx>(infcx: &InferCtxt<'a,'tcx>,
392392
}
393393
}
394394

395+
pub fn normalize_param_env_or_error<'a,'tcx>(unnormalized_env: ty::ParameterEnvironment<'a,'tcx>,
396+
cause: ObligationCause<'tcx>)
397+
-> ty::ParameterEnvironment<'a,'tcx>
398+
{
399+
match normalize_param_env(&unnormalized_env, cause) {
400+
Ok(p) => p,
401+
Err(errors) => {
402+
// I'm not wild about reporting errors here; I'd prefer to
403+
// have the errors get reported at a defined place (e.g.,
404+
// during typeck). Instead I have all parameter
405+
// environments, in effect, going through this function
406+
// and hence potentially reporting errors. This ensurse of
407+
// course that we never forget to normalize (the
408+
// alternative seemed like it would involve a lot of
409+
// manual invocations of this fn -- and then we'd have to
410+
// deal with the errors at each of those sites).
411+
//
412+
// In any case, in practice, typeck constructs all the
413+
// parameter environments once for every fn as it goes,
414+
// and errors will get reported then; so after typeck we
415+
// can be sure that no errors should occur.
416+
let infcx = infer::new_infer_ctxt(unnormalized_env.tcx);
417+
report_fulfillment_errors(&infcx, &errors);
418+
419+
// Normalized failed? use what they gave us, it's better than nothing.
420+
unnormalized_env
421+
}
422+
}
423+
}
424+
425+
pub fn normalize_param_env<'a,'tcx>(param_env: &ty::ParameterEnvironment<'a,'tcx>,
426+
cause: ObligationCause<'tcx>)
427+
-> Result<ty::ParameterEnvironment<'a,'tcx>,
428+
Vec<FulfillmentError<'tcx>>>
429+
{
430+
let tcx = param_env.tcx;
431+
432+
debug!("normalize_param_env(param_env={})",
433+
param_env.repr(tcx));
434+
435+
let predicates: Vec<ty::Predicate<'tcx>> = {
436+
let infcx = infer::new_infer_ctxt(tcx);
437+
let mut selcx = &mut SelectionContext::new(&infcx, param_env);
438+
let mut fulfill_cx = FulfillmentContext::new();
439+
let Normalized { value: predicates, obligations } =
440+
project::normalize(selcx, cause, &param_env.caller_bounds);
441+
for obligation in obligations.into_iter() {
442+
fulfill_cx.register_predicate_obligation(selcx.infcx(), obligation);
443+
}
444+
try!(fulfill_cx.select_all_or_error(selcx.infcx(), param_env));
445+
predicates.iter().map(|p| infcx.resolve_type_vars_if_possible(p)).collect()
446+
};
447+
448+
debug!("normalize_param_env: predicates={}",
449+
predicates.repr(tcx));
450+
451+
Ok(param_env.with_caller_bounds(predicates))
452+
}
453+
395454
impl<'tcx,O> Obligation<'tcx,O> {
396455
pub fn new(cause: ObligationCause<'tcx>,
397456
trait_ref: O)

src/librustc/middle/traits/object_safety.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,15 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
122122
trait_def_id: ast::DefId)
123123
-> bool
124124
{
125-
let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
126-
let param_env = ty::construct_parameter_environment(tcx,
127-
&trait_def.generics,
128-
ast::DUMMY_NODE_ID);
129-
let predicates = param_env.caller_bounds.predicates.as_slice().to_vec();
130125
let sized_def_id = match tcx.lang_items.sized_trait() {
131126
Some(def_id) => def_id,
132127
None => { return false; /* No Sized trait, can't require it! */ }
133128
};
134129

135130
// Search for a predicate like `Self : Sized` amongst the trait bounds.
131+
let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
132+
let free_substs = ty::construct_free_substs(tcx, &trait_def.generics, ast::DUMMY_NODE_ID);
133+
let predicates = trait_def.generics.to_bounds(tcx, &free_substs).predicates.into_vec();
136134
elaborate_predicates(tcx, predicates)
137135
.any(|predicate| {
138136
match predicate {

0 commit comments

Comments
 (0)