diff options
| author | scalexm <alexandre@scalexm.fr> | 2018-11-30 15:06:49 +0100 |
|---|---|---|
| committer | scalexm <alexandre@scalexm.fr> | 2018-12-27 19:21:16 +0100 |
| commit | 3790f08a42afd07835f9eec72db1d56235d32eed (patch) | |
| tree | 5f9aca92707aa0b5c70d792cbf20e8b5627ad2d6 | |
| parent | 8e2bdaacac450695d62a34365803845378bc9121 (diff) | |
Fix `tcx.environment` for inherent impls
| -rw-r--r-- | src/librustc_traits/lowering/environment.rs | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index abd776fab86..962a145814c 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -216,56 +216,73 @@ crate fn environment<'a, 'tcx>( let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); let node = tcx.hir().get(node_id); - let mut is_fn = false; - let mut is_impl = false; - match node { + enum NodeKind { + TraitImpl, + InherentImpl, + Fn, + Other, + }; + + let node_kind = match node { Node::TraitItem(item) => match item.node { - TraitItemKind::Method(..) => is_fn = true, - _ => (), + TraitItemKind::Method(..) => NodeKind::Fn, + _ => NodeKind::Other, } Node::ImplItem(item) => match item.node { - ImplItemKind::Method(..) => is_fn = true, - _ => (), + ImplItemKind::Method(..) => NodeKind::Fn, + _ => NodeKind::Other, } Node::Item(item) => match item.node { - ItemKind::Impl(..) => is_impl = true, - ItemKind::Fn(..) => is_fn = true, - _ => (), + ItemKind::Impl(.., Some(..), _, _) => NodeKind::TraitImpl, + ItemKind::Impl(.., None, _, _) => NodeKind::InherentImpl, + ItemKind::Fn(..) => NodeKind::Fn, + _ => NodeKind::Other, } Node::ForeignItem(item) => match item.node { - ForeignItemKind::Fn(..) => is_fn = true, - _ => (), + ForeignItemKind::Fn(..) => NodeKind::Fn, + _ => NodeKind::Other, } // FIXME: closures? - _ => (), - } + _ => NodeKind::Other, + }; let mut input_tys = FxHashSet::default(); - // In an impl, we assume that the header trait ref and all its constituents - // are well-formed. - if is_impl { - let trait_ref = tcx.impl_trait_ref(def_id) - .expect("not an impl"); + match node_kind { + // In a trait impl, we assume that the header trait ref and all its + // constituents are well-formed. + NodeKind::TraitImpl => { + let trait_ref = tcx.impl_trait_ref(def_id) + .expect("not an impl"); - input_tys.extend( - trait_ref.input_types().flat_map(|ty| ty.walk()) - ); - } + input_tys.extend( + trait_ref.input_types().flat_map(|ty| ty.walk()) + ); + } - // In an fn, we assume that the arguments and all their constituents are - // well-formed. - if is_fn { - let fn_sig = tcx.fn_sig(def_id); - let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig); + // In an inherent impl, we assume that the receiver type and all its + // constituents are well-formed. + NodeKind::InherentImpl => { + let self_ty = tcx.type_of(def_id); + input_tys.extend(self_ty.walk()); + } - input_tys.extend( - fn_sig.inputs().iter().flat_map(|ty| ty.walk()) - ); + // In an fn, we assume that the arguments and all their constituents are + // well-formed. + NodeKind::Fn => { + let fn_sig = tcx.fn_sig(def_id); + let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig); + + input_tys.extend( + fn_sig.inputs().iter().flat_map(|ty| ty.walk()) + ); + } + + NodeKind::Other => (), } let clauses = clauses.chain( |
