mod.rs 22.7 KB
Newer Older
1
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 3 4 5 6 7 8 9 10
// 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.

11 12
// Coherence phase
//
13 14 15 16
// The job of the coherence phase of typechecking is to ensure that
// each trait has at most one implementation for each type. This is
// done by the orphan and overlap modules. Then we build up various
// mappings. That mapping code resides here.
17

18

19
use metadata::csearch::{each_impl, get_impl_trait};
20
use metadata::csearch;
21
use middle::subst::{self, Subst};
22
use middle::ty::RegionEscape;
23
use middle::ty::{ImplContainer, ImplOrTraitItemId, MethodTraitItemId};
N
Niko Matsakis 已提交
24
use middle::ty::{ParameterEnvironment, TypeTraitItemId, lookup_item_type};
J
Jorge Aparicio 已提交
25
use middle::ty::{Ty, ty_bool, ty_char, ty_enum, ty_err};
26
use middle::ty::{ty_param, TypeScheme, ty_ptr};
27
use middle::ty::{ty_rptr, ty_struct, ty_trait, ty_tup};
N
Niko Matsakis 已提交
28
use middle::ty::{ty_str, ty_vec, ty_float, ty_infer, ty_int, ty_open};
29
use middle::ty::{ty_uint, ty_closure, ty_uniq, ty_bare_fn};
30
use middle::ty::{ty_projection};
31
use middle::ty;
N
Niko Matsakis 已提交
32
use CrateCtxt;
33 34
use middle::infer::combine::Combine;
use middle::infer::InferCtxt;
35
use middle::infer::{new_infer_ctxt};
36 37 38
use std::collections::{HashSet};
use std::cell::RefCell;
use std::rc::Rc;
39
use syntax::ast::{Crate, DefId};
40 41
use syntax::ast::{Item, ItemImpl};
use syntax::ast::{LOCAL_CRATE, TraitRef};
42
use syntax::ast;
43
use syntax::ast_map::NodeItem;
44
use syntax::ast_map;
45
use syntax::ast_util::{local_def};
46
use syntax::codemap::{Span};
47
use syntax::parse::token;
48
use syntax::visit;
49 50
use util::nodemap::{DefIdMap, FnvHashMap};
use util::ppaux::Repr;
51

52
mod impls;
53 54
mod orphan;
mod overlap;
55
mod unsafety;
56

57 58 59 60 61 62 63 64 65
// Returns the def ID of the base type, if there is one.
fn get_base_type_def_id<'a, 'tcx>(inference_context: &InferCtxt<'a, 'tcx>,
                                  span: Span,
                                  ty: Ty<'tcx>)
                                  -> Option<DefId> {
    match ty.sty {
        ty_enum(def_id, _) |
        ty_struct(def_id, _) => {
            Some(def_id)
66
        }
67

68
        ty_trait(ref t) => {
69
            Some(t.principal_def_id())
N
Nick Cameron 已提交
70
        }
71

A
Alex Crichton 已提交
72 73 74 75
        ty_uniq(_) => {
            inference_context.tcx.lang_items.owned_box()
        }

76
        ty_bool | ty_char | ty_int(..) | ty_uint(..) | ty_float(..) |
J
Jorge Aparicio 已提交
77
        ty_str(..) | ty_vec(..) | ty_bare_fn(..) | ty_tup(..) |
A
Alex Crichton 已提交
78
        ty_param(..) | ty_err | ty_open(..) |
79
        ty_ptr(_) | ty_rptr(_, _) | ty_projection(..) => {
B
Brian Anderson 已提交
80
            None
81 82
        }

83
        ty_infer(..) | ty_closure(..) => {
84 85 86 87
            // `ty` comes from a user declaration so we should only expect types
            // that the user can type
            inference_context.tcx.sess.span_bug(
                span,
J
Jorge Aparicio 已提交
88 89
                &format!("coherence encountered unexpected type searching for base type: {}",
                        ty.repr(inference_context.tcx))[]);
90 91 92
        }
    }
}
93

94 95 96
struct CoherenceChecker<'a, 'tcx: 'a> {
    crate_context: &'a CrateCtxt<'a, 'tcx>,
    inference_context: InferCtxt<'a, 'tcx>,
97
    inherent_impls: RefCell<DefIdMap<Rc<RefCell<Vec<ast::DefId>>>>>,
98 99
}

100 101
struct CoherenceCheckVisitor<'a, 'tcx: 'a> {
    cc: &'a CoherenceChecker<'a, 'tcx>
E
Eduard Burtescu 已提交
102
}
103

104
impl<'a, 'tcx, 'v> visit::Visitor<'v> for CoherenceCheckVisitor<'a, 'tcx> {
105
    fn visit_item(&mut self, item: &Item) {
E
Eduard Burtescu 已提交
106

107
        //debug!("(checking coherence) item '{}'", token::get_ident(item.ident));
E
Eduard Burtescu 已提交
108 109

        match item.node {
110
            ItemImpl(_, _, _, ref opt_trait, _, _) => {
E
Eduard Burtescu 已提交
111 112
                match opt_trait.clone() {
                    Some(opt_trait) => {
N
Nick Cameron 已提交
113
                        self.cc.check_implementation(item, &[opt_trait]);
114
                    }
N
Nick Cameron 已提交
115
                    None => self.cc.check_implementation(item, &[])
E
Eduard Burtescu 已提交
116 117 118 119 120 121
                }
            }
            _ => {
                // Nothing to do.
            }
        };
122

123
        visit::walk_item(self, item);
124 125 126
    }
}

127
impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
128
    fn check(&self, krate: &Crate) {
129 130 131 132
        // Check implementations and traits. This populates the tables
        // containing the inherent methods and extension methods. It also
        // builds up the trait inheritance table.
        let mut visitor = CoherenceCheckVisitor { cc: self };
133
        visit::walk_crate(&mut visitor, krate);
134

135 136 137 138 139 140 141 142
        // Copy over the inherent impls we gathered up during the walk into
        // the tcx.
        let mut tcx_inherent_impls =
            self.crate_context.tcx.inherent_impls.borrow_mut();
        for (k, v) in self.inherent_impls.borrow().iter() {
            tcx_inherent_impls.insert((*k).clone(),
                                      Rc::new((*v.borrow()).clone()));
        }
143 144 145 146 147

        // Bring in external crates. It's fine for this to happen after the
        // coherence checks, because we ensure by construction that no errors
        // can happen at link time.
        self.add_external_crates();
148 149 150 151 152

        // Populate the table of destructors. It might seem a bit strange to
        // do this here, but it's actually the most convenient place, since
        // the coherence tables contain the trait -> type mappings.
        self.populate_destructor_table();
N
Niko Matsakis 已提交
153 154 155

        // Check to make sure implementations of `Copy` are legal.
        self.check_implementations_of_copy();
156 157
    }

158 159
    fn check_implementation(&self,
                            item: &Item,
E
Eduard Burtescu 已提交
160
                            associated_traits: &[TraitRef]) {
161
        let tcx = self.crate_context.tcx;
E
Eduard Burtescu 已提交
162 163
        let impl_did = local_def(item.id);
        let self_type = ty::lookup_item_type(tcx, impl_did);
164 165 166 167

        // If there are no traits, then this implementation must have a
        // base type.

168
        let impl_items = self.create_impl_from_item(item);
169

D
Daniel Micay 已提交
170
        for associated_trait in associated_traits.iter() {
171 172
            let trait_ref = ty::node_id_to_trait_ref(self.crate_context.tcx,
                                                     associated_trait.ref_id);
173
            debug!("(checking implementation) adding impl for trait '{}', item '{}'",
174
                   trait_ref.repr(self.crate_context.tcx),
175
                   token::get_ident(item.ident));
176

177 178 179
            enforce_trait_manually_implementable(self.crate_context.tcx,
                                                 item.span,
                                                 trait_ref.def_id);
E
Eduard Burtescu 已提交
180
            self.add_trait_impl(trait_ref.def_id, impl_did);
181
        }
182 183

        // Add the implementation to the mapping from implementation to base
184 185
        // type def ID, if there is a base type for this implementation and
        // the implementation does not have any associated traits.
E
Eduard Burtescu 已提交
186
        match get_base_type_def_id(&self.inference_context,
L
Lindsey Kuper 已提交
187 188
                                   item.span,
                                   self_type.ty) {
B
Brian Anderson 已提交
189
            None => {
190 191
                // Nothing to do.
            }
B
Brian Anderson 已提交
192
            Some(base_type_def_id) => {
193
                // FIXME: Gather up default methods?
194
                if associated_traits.len() == 0 {
E
Eduard Burtescu 已提交
195
                    self.add_inherent_impl(base_type_def_id, impl_did);
196
                }
197 198
            }
        }
199

200
        tcx.impl_items.borrow_mut().insert(impl_did, impl_items);
201 202
    }

203 204 205
    // Creates default method IDs and performs type substitutions for an impl
    // and trait pair. Then, for each provided method in the trait, inserts a
    // `ProvidedMethodInfo` instance into the `provided_method_sources` map.
206 207 208
    fn instantiate_default_methods(
            &self,
            impl_id: DefId,
209
            trait_ref: &ty::TraitRef<'tcx>,
210
            all_impl_items: &mut Vec<ImplOrTraitItemId>) {
211
        let tcx = self.crate_context.tcx;
212
        debug!("instantiate_default_methods(impl_id={:?}, trait_ref={})",
213 214
               impl_id, trait_ref.repr(tcx));

215
        let impl_type_scheme = ty::lookup_item_type(tcx, impl_id);
216

217 218
        let prov = ty::provided_trait_methods(tcx, trait_ref.def_id);
        for trait_method in prov.iter() {
219
            // Synthesize an ID.
220
            let new_id = tcx.sess.next_node_id();
221 222
            let new_did = local_def(new_id);

223
            debug!("new_did={:?} trait_method={}", new_did, trait_method.repr(tcx));
224 225 226

            // Create substitutions for the various trait parameters.
            let new_method_ty =
E
Eduard Burtescu 已提交
227
                Rc::new(subst_receiver_types_in_method_ty(
228 229
                    tcx,
                    impl_id,
230
                    &impl_type_scheme,
231 232
                    trait_ref,
                    new_did,
E
Eduard Burtescu 已提交
233 234
                    &**trait_method,
                    Some(trait_method.def_id)));
235

236
            debug!("new_method_ty={}", new_method_ty.repr(tcx));
237
            all_impl_items.push(MethodTraitItemId(new_did));
238

239 240 241
            // construct the polytype for the method based on the
            // method_ty.  it will have all the generics from the
            // impl, plus its own.
242
            let new_polytype = ty::TypeScheme {
243
                generics: new_method_ty.generics.clone(),
244 245
                ty: ty::mk_bare_fn(tcx, Some(new_did),
                                   tcx.mk_bare_fn(new_method_ty.fty.clone()))
246
            };
247
            debug!("new_polytype={}", new_polytype.repr(tcx));
248

249
            tcx.tcache.borrow_mut().insert(new_did, new_polytype);
250 251 252
            tcx.impl_or_trait_items
               .borrow_mut()
               .insert(new_did, ty::MethodTraitItem(new_method_ty));
253 254 255

            // Pair the new synthesized ID up with the
            // ID of the method.
256 257
            self.crate_context.tcx.provided_method_sources.borrow_mut()
                .insert(new_did, trait_method.def_id);
258 259 260
        }
    }

E
Eduard Burtescu 已提交
261
    fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
262
        match self.inherent_impls.borrow().get(&base_def_id) {
E
Eduard Burtescu 已提交
263
            Some(implementation_list) => {
E
Eduard Burtescu 已提交
264
                implementation_list.borrow_mut().push(impl_def_id);
E
Eduard Burtescu 已提交
265
                return;
266
            }
E
Eduard Burtescu 已提交
267
            None => {}
268
        }
269

270 271 272
        self.inherent_impls.borrow_mut().insert(
            base_def_id,
            Rc::new(RefCell::new(vec!(impl_def_id))));
273 274
    }

E
Eduard Burtescu 已提交
275
    fn add_trait_impl(&self, base_def_id: DefId, impl_def_id: DefId) {
276
        debug!("add_trait_impl: base_def_id={:?} impl_def_id={:?}",
277
               base_def_id, impl_def_id);
E
Eduard Burtescu 已提交
278 279
        ty::record_trait_implementation(self.crate_context.tcx,
                                        base_def_id,
E
Eduard Burtescu 已提交
280
                                        impl_def_id);
281 282
    }

E
Eduard Burtescu 已提交
283
    fn get_self_type_for_implementation(&self, impl_did: DefId)
284
                                        -> TypeScheme<'tcx> {
285
        self.crate_context.tcx.tcache.borrow()[impl_did].clone()
286
    }
287

288 289
    // Converts an implementation in the AST to a vector of items.
    fn create_impl_from_item(&self, item: &Item) -> Vec<ImplOrTraitItemId> {
290
        match item.node {
291
            ItemImpl(_, _, _, ref trait_refs, _, ref ast_items) => {
292 293 294 295
                let mut items: Vec<ImplOrTraitItemId> =
                        ast_items.iter()
                                 .map(|ast_item| {
                            match *ast_item {
296
                                ast::MethodImplItem(ref ast_method) => {
297 298 299
                                    MethodTraitItemId(
                                        local_def(ast_method.id))
                                }
300 301 302
                                ast::TypeImplItem(ref typedef) => {
                                    TypeTraitItemId(local_def(typedef.id))
                                }
303 304
                            }
                        }).collect();
305

D
Daniel Micay 已提交
306
                for trait_ref in trait_refs.iter() {
307 308 309 310 311
                    let ty_trait_ref = ty::node_id_to_trait_ref(
                        self.crate_context.tcx,
                        trait_ref.ref_id);

                    self.instantiate_default_methods(local_def(item.id),
E
Eduard Burtescu 已提交
312
                                                     &*ty_trait_ref,
313
                                                     &mut items);
314 315
                }

316
                items
317
            }
B
Brian Anderson 已提交
318
            _ => {
319
                self.crate_context.tcx.sess.span_bug(item.span,
J
Jeong YunWon 已提交
320
                                                     "can't convert a non-impl to an impl");
321 322 323
            }
        }
    }
324

325 326
    // External crate handling

E
Eduard Burtescu 已提交
327 328 329
    fn add_external_impl(&self,
                         impls_seen: &mut HashSet<DefId>,
                         impl_def_id: DefId) {
330
        let tcx = self.crate_context.tcx;
331 332
        let impl_items = csearch::get_impl_items(&tcx.sess.cstore,
                                                 impl_def_id);
333

334
        // Make sure we don't visit the same implementation multiple times.
E
Eduard Burtescu 已提交
335
        if !impls_seen.insert(impl_def_id) {
336 337 338 339
            // Skip this one.
            return
        }
        // Good. Continue.
340

E
Eduard Burtescu 已提交
341 342
        let _ = lookup_item_type(tcx, impl_def_id);
        let associated_traits = get_impl_trait(tcx, impl_def_id);
343

344 345
        // Do a sanity check.
        assert!(associated_traits.is_some());
346

347
        // Record all the trait items.
D
Daniel Micay 已提交
348
        for trait_ref in associated_traits.iter() {
349
            self.add_trait_impl(trait_ref.def_id, impl_def_id);
350
        }
351

352 353
        // For any methods that use a default implementation, add them to
        // the map. This is a bit unfortunate.
354 355 356 357 358 359 360 361 362 363
        for item_def_id in impl_items.iter() {
            let impl_item = ty::impl_or_trait_item(tcx, item_def_id.def_id());
            match impl_item {
                ty::MethodTraitItem(ref method) => {
                    for &source in method.provided_source.iter() {
                        tcx.provided_method_sources
                           .borrow_mut()
                           .insert(item_def_id.def_id(), source);
                    }
                }
364
                ty::TypeTraitItem(_) => {}
365
            }
366 367
        }

368
        tcx.impl_items.borrow_mut().insert(impl_def_id, impl_items);
369 370
    }

371 372
    // Adds implementations and traits from external crates to the coherence
    // info.
E
Eduard Burtescu 已提交
373
    fn add_external_crates(&self) {
374
        let mut impls_seen = HashSet::new();
375

E
Eduard Burtescu 已提交
376
        let crate_store = &self.crate_context.tcx.sess.cstore;
S
Steven Fackler 已提交
377
        crate_store.iter_crate_data(|crate_number, _crate_metadata| {
378
            each_impl(crate_store, crate_number, |def_id| {
379
                assert_eq!(crate_number, def_id.krate);
380
                self.add_external_impl(&mut impls_seen, def_id)
381 382
            })
        })
383
    }
384 385 386 387 388

    //
    // Destructors
    //

E
Eduard Burtescu 已提交
389
    fn populate_destructor_table(&self) {
390
        let tcx = self.crate_context.tcx;
A
Alex Crichton 已提交
391 392 393
        let drop_trait = match tcx.lang_items.drop_trait() {
            Some(id) => id, None => { return }
        };
394

395
        let impl_items = tcx.impl_items.borrow();
396
        let trait_impls = match tcx.trait_impls.borrow().get(&drop_trait).cloned() {
397
            None => return, // No types with (new-style) dtors present.
E
Eduard Burtescu 已提交
398 399
            Some(found_impls) => found_impls
        };
400

E
Eduard Burtescu 已提交
401
        for &impl_did in trait_impls.borrow().iter() {
402
            let items = &(*impl_items)[impl_did];
403
            if items.len() < 1 {
404
                // We'll error out later. For now, just don't ICE.
405
                continue;
406
            }
407
            let method_def_id = items[0];
408

E
Eduard Burtescu 已提交
409
            let self_type = self.get_self_type_for_implementation(impl_did);
410
            match self_type.ty.sty {
411
                ty::ty_enum(type_def_id, _) |
412
                ty::ty_struct(type_def_id, _) |
413
                ty::ty_closure(type_def_id, _, _) => {
414 415 416 417 418 419
                    tcx.destructor_for_type
                       .borrow_mut()
                       .insert(type_def_id, method_def_id.def_id());
                    tcx.destructors
                       .borrow_mut()
                       .insert(method_def_id.def_id());
420 421 422
                }
                _ => {
                    // Destructors only work on nominal types.
E
Eduard Burtescu 已提交
423
                    if impl_did.krate == ast::LOCAL_CRATE {
P
Patrick Walton 已提交
424
                        {
E
Eduard Burtescu 已提交
425
                            match tcx.map.find(impl_did.node) {
426
                                Some(ast_map::NodeItem(item)) => {
J
Jakub Wieczorek 已提交
427 428
                                    span_err!(tcx.sess, item.span, E0120,
                                        "the Drop trait may only be implemented on structures");
P
Patrick Walton 已提交
429 430 431 432 433
                                }
                                _ => {
                                    tcx.sess.bug("didn't find impl in ast \
                                                  map");
                                }
434 435 436
                            }
                        }
                    } else {
J
Jeong YunWon 已提交
437 438
                        tcx.sess.bug("found external impl of Drop trait on \
                                      something other than a struct");
439 440 441 442 443
                    }
                }
            }
        }
    }
N
Niko Matsakis 已提交
444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468

    /// Ensures that implementations of the built-in trait `Copy` are legal.
    fn check_implementations_of_copy(&self) {
        let tcx = self.crate_context.tcx;
        let copy_trait = match tcx.lang_items.copy_trait() {
            Some(id) => id,
            None => return,
        };

        let trait_impls = match tcx.trait_impls
                                   .borrow()
                                   .get(&copy_trait)
                                   .cloned() {
            None => {
                debug!("check_implementations_of_copy(): no types with \
                        implementations of `Copy` found");
                return
            }
            Some(found_impls) => found_impls
        };

        // Clone first to avoid a double borrow error.
        let trait_impls = trait_impls.borrow().clone();

        for &impl_did in trait_impls.iter() {
469 470 471
            debug!("check_implementations_of_copy: impl_did={}",
                   impl_did.repr(tcx));

N
Niko Matsakis 已提交
472 473 474 475 476 477 478
            if impl_did.krate != ast::LOCAL_CRATE {
                debug!("check_implementations_of_copy(): impl not in this \
                        crate");
                continue
            }

            let self_type = self.get_self_type_for_implementation(impl_did);
479 480 481
            debug!("check_implementations_of_copy: self_type={} (bound)",
                   self_type.repr(tcx));

N
Niko Matsakis 已提交
482
            let span = tcx.map.span(impl_did.node);
483
            let param_env = ParameterEnvironment::for_item(tcx, impl_did.node);
N
Niko Matsakis 已提交
484
            let self_type = self_type.ty.subst(tcx, &param_env.free_substs);
485
            assert!(!self_type.has_escaping_regions());
N
Niko Matsakis 已提交
486

487
            debug!("check_implementations_of_copy: self_type={} (free)",
488 489
                   self_type.repr(tcx));

490
            match ty::can_type_implement_copy(&param_env, span, self_type) {
N
Niko Matsakis 已提交
491 492
                Ok(()) => {}
                Err(ty::FieldDoesNotImplementCopy(name)) => {
B
Brian Anderson 已提交
493 494
                       span_err!(tcx.sess, span, E0204,
                                 "the trait `Copy` may not be \
N
Niko Matsakis 已提交
495 496
                                          implemented for this type; field \
                                          `{}` does not implement `Copy`",
B
Brian Anderson 已提交
497
                                         token::get_name(name))
N
Niko Matsakis 已提交
498 499
                }
                Err(ty::VariantDoesNotImplementCopy(name)) => {
B
Brian Anderson 已提交
500 501
                       span_err!(tcx.sess, span, E0205,
                                 "the trait `Copy` may not be \
N
Niko Matsakis 已提交
502 503
                                          implemented for this type; variant \
                                          `{}` does not implement `Copy`",
B
Brian Anderson 已提交
504
                                         token::get_name(name))
N
Niko Matsakis 已提交
505 506
                }
                Err(ty::TypeIsStructural) => {
B
Brian Anderson 已提交
507
                       span_err!(tcx.sess, span, E0206,
N
Niko Matsakis 已提交
508 509 510 511
                                 "the trait `Copy` may not be implemented \
                                  for this type; type is not a structure or \
                                  enumeration")
                }
512 513 514 515 516
                Err(ty::TypeHasDestructor) => {
                    span_err!(tcx.sess, span, E0184,
                              "the trait `Copy` may not be implemented for this type; \
                               the type has a destructor");
                }
N
Niko Matsakis 已提交
517 518 519
            }
        }
    }
520 521
}

522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
fn enforce_trait_manually_implementable(tcx: &ty::ctxt, sp: Span, trait_def_id: ast::DefId) {
    if tcx.sess.features.borrow().unboxed_closures {
        // the feature gate allows all of them
        return
    }
    let did = Some(trait_def_id);
    let li = &tcx.lang_items;

    let trait_name = if did == li.fn_trait() {
        "Fn"
    } else if did == li.fn_mut_trait() {
        "FnMut"
    } else if did == li.fn_once_trait() {
        "FnOnce"
    } else {
        return // everything OK
    };
N
Nick Cameron 已提交
539
    span_err!(tcx.sess, sp, E0183, "manual implementations of `{}` are experimental", trait_name);
540 541 542 543
    span_help!(tcx.sess, sp,
               "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
}

544 545
fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
                                           impl_id: ast::DefId,
546
                                           impl_type_scheme: &ty::TypeScheme<'tcx>,
547 548 549 550 551
                                           trait_ref: &ty::TraitRef<'tcx>,
                                           new_def_id: ast::DefId,
                                           method: &ty::Method<'tcx>,
                                           provided_source: Option<ast::DefId>)
                                           -> ty::Method<'tcx>
552
{
553
    let combined_substs = ty::make_substs_for_receiver_types(tcx, trait_ref, method);
554 555 556 557 558 559 560 561 562

    debug!("subst_receiver_types_in_method_ty: combined_substs={}",
           combined_substs.repr(tcx));

    let mut method_generics = method.generics.subst(tcx, &combined_substs);

    // replace the type parameters declared on the trait with those
    // from the impl
    for &space in [subst::TypeSpace, subst::SelfSpace].iter() {
563 564
        method_generics.types.replace(
            space,
565
            impl_type_scheme.generics.types.get_slice(space).to_vec());
566 567
        method_generics.regions.replace(
            space,
568
            impl_type_scheme.generics.regions.get_slice(space).to_vec());
569
    }
570

571 572
    debug!("subst_receiver_types_in_method_ty: method_generics={}",
           method_generics.repr(tcx));
573

574
    let method_fty = method.fty.subst(tcx, &combined_substs);
575

576 577
    debug!("subst_receiver_types_in_method_ty: method_ty={}",
           method.fty.repr(tcx));
578

579
    ty::Method::new(
580
        method.name,
581 582
        method_generics,
        method_fty,
583 584
        method.explicit_self,
        method.vis,
585
        new_def_id,
586
        ImplContainer(impl_id),
587
        provided_source
588
    )
589 590
}

591
pub fn check_coherence(crate_context: &CrateCtxt) {
E
Eduard Burtescu 已提交
592 593 594
    CoherenceChecker {
        crate_context: crate_context,
        inference_context: new_infer_ctxt(crate_context.tcx),
595
        inherent_impls: RefCell::new(FnvHashMap()),
596
    }.check(crate_context.tcx.map.krate());
597
    impls::check(crate_context.tcx);
598
    unsafety::check(crate_context.tcx);
599 600
    orphan::check(crate_context.tcx);
    overlap::check(crate_context.tcx);
601
}