//! Orphan checker: every impl either implements a trait defined in this
//! crate or pertains to a type defined in this crate.

use rustc::traits;
use rustc::ty::{self, TyCtxt};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir;

use rustc_error_codes::*;

pub fn check(tcx: TyCtxt<'_>) {
    let mut orphan = OrphanChecker { tcx };
    tcx.hir().krate().visit_all_item_likes(&mut orphan);
}

struct OrphanChecker<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
    /// Checks exactly one impl for orphan rules and other such
    /// restrictions. In this fn, it can happen that multiple errors
    /// apply to a specific impl, so just return after reporting one
    /// to prevent inundating the user with a bunch of similar error
    /// reports.
    fn visit_item(&mut self, item: &hir::Item) {
        let def_id = self.tcx.hir().local_def_id(item.hir_id);
        // "Trait" impl
        if let hir::ItemKind::Impl(.., generics, Some(tr), impl_ty, _) = &item.kind {
            debug!("coherence2::orphan check: trait impl {}",
                   self.tcx.hir().node_to_string(item.hir_id));
            let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
            let trait_def_id = trait_ref.def_id;
            let cm = self.tcx.sess.source_map();
            let sp = cm.def_span(item.span);
            match traits::orphan_check(self.tcx, def_id) {
                Ok(()) => {}
                Err(traits::OrphanCheckErr::NonLocalInputType(tys)) => {
                    let mut err = struct_span_err!(
                        self.tcx.sess,
                        sp,
                        E0117,
                        "only traits defined in the current crate can be implemented for \
                         arbitrary types"
                    );
                    err.span_label(sp, "impl doesn't use only types from inside the current crate");
                    for (ty, is_target_ty) in &tys {
                        let mut ty = *ty;
                        self.tcx.infer_ctxt().enter(|infcx| {
                            // Remove the lifetimes unnecessary for this error.
                            ty = infcx.freshen(ty);
                        });
                        ty = match ty.kind {
                            // Remove the type arguments from the output, as they are not relevant.
                            // You can think of this as the reverse of `resolve_vars_if_possible`.
                            // That way if we had `Vec<MyType>`, we will properly attribute the
                            // problem to `Vec<T>` and avoid confusing the user if they were to see
                            // `MyType` in the error.
                            ty::Adt(def, _) => self.tcx.mk_adt(def, ty::List::empty()),
                            _ => ty,
                        };
                        let this = "this".to_string();
                        let (ty, postfix) = match &ty.kind {
                            ty::Slice(_) => (this, " because slices are always foreign"),
                            ty::Array(..) => (this, " because arrays are always foreign"),
                            ty::Tuple(..) => (this, " because tuples are always foreign"),
                            _ => (format!("`{}`", ty), ""),
                        };
                        let msg = format!("{} is not defined in the current crate{}", ty, postfix);
                        if *is_target_ty {
                            // Point at `D<A>` in `impl<A, B> for C<B> in D<A>`
                            err.span_label(impl_ty.span, &msg);
                        } else {
                            // Point at `C<B>` in `impl<A, B> for C<B> in D<A>`
                            err.span_label(tr.path.span, &msg);
                        }
                    }
                    err.note("define and implement a trait or new type instead");
                    err.emit();
                    return;
                }
                Err(traits::OrphanCheckErr::UncoveredTy(param_ty, local_type)) => {
                    let mut sp = sp;
                    for param in &generics.params {
                        if param.name.ident().to_string() == param_ty.to_string() {
                            sp = param.span;
                        }
                    }

                    match local_type {
                        Some(local_type) => {
                            struct_span_err!(
                                self.tcx.sess,
                                sp,
                                E0210,
                                "type parameter `{}` must be covered by another type \
                                when it appears before the first local type (`{}`)",
                                param_ty,
                                local_type
                            ).span_label(sp, format!(
                                "type parameter `{}` must be covered by another type \
                                when it appears before the first local type (`{}`)",
                                param_ty,
                                local_type
                            )).note("implementing a foreign trait is only possible if at \
                                    least one of the types for which is it implemented is local, \
                                    and no uncovered type parameters appear before that first \
                                    local type"
                            ).note("in this case, 'before' refers to the following order: \
                                    `impl<..> ForeignTrait<T1, ..., Tn> for T0`, \
                                    where `T0` is the first and `Tn` is the last"
                            ).emit();
                        }
                        None => {
                            struct_span_err!(
                                self.tcx.sess,
                                sp,
                                E0210,
                                "type parameter `{}` must be used as the type parameter for some \
                                local type (e.g., `MyStruct<{}>`)",
                                param_ty,
                                param_ty
                            ).span_label(sp, format!(
                                "type parameter `{}` must be used as the type parameter for some \
                                local type",
                                param_ty,
                            )).note("implementing a foreign trait is only possible if at \
                                    least one of the types for which is it implemented is local"
                            ).note("only traits defined in the current crate can be \
                                    implemented for a type parameter"
                            ).emit();
                        }
                    };
                    return;
                }
            }

            // In addition to the above rules, we restrict impls of auto traits
            // so that they can only be implemented on nominal types, such as structs,
            // enums or foreign types. To see why this restriction exists, consider the
            // following example (#22978). Imagine that crate A defines an auto trait
            // `Foo` and a fn that operates on pairs of types:
            //
            // ```
            // // Crate A
            // auto trait Foo { }
            // fn two_foos<A:Foo,B:Foo>(..) {
            //     one_foo::<(A,B)>(..)
            // }
            // fn one_foo<T:Foo>(..) { .. }
            // ```
            //
            // This type-checks fine; in particular the fn
            // `two_foos` is able to conclude that `(A,B):Foo`
            // because `A:Foo` and `B:Foo`.
            //
            // Now imagine that crate B comes along and does the following:
            //
            // ```
            // struct A { }
            // struct B { }
            // impl Foo for A { }
            // impl Foo for B { }
            // impl !Send for (A, B) { }
            // ```
            //
            // This final impl is legal according to the orpan
            // rules, but it invalidates the reasoning from
            // `two_foos` above.
            debug!("trait_ref={:?} trait_def_id={:?} trait_is_auto={}",
                   trait_ref,
                   trait_def_id,
                   self.tcx.trait_is_auto(trait_def_id));
            if self.tcx.trait_is_auto(trait_def_id) &&
               !trait_def_id.is_local() {
                let self_ty = trait_ref.self_ty();
                let opt_self_def_id = match self_ty.kind {
                    ty::Adt(self_def, _) => Some(self_def.did),
                    ty::Foreign(did) => Some(did),
                    _ => None,
                };

                let msg = match opt_self_def_id {
                    // We only want to permit nominal types, but not *all* nominal types.
                    // They must be local to the current crate, so that people
                    // can't do `unsafe impl Send for Rc<SomethingLocal>` or
                    // `impl !Send for Box<SomethingLocalAndSend>`.
                    Some(self_def_id) => {
                        if self_def_id.is_local() {
                            None
                        } else {
                            Some((
                                format!("cross-crate traits with a default impl, like `{}`, \
                                         can only be implemented for a struct/enum type \
                                         defined in the current crate",
                                        self.tcx.def_path_str(trait_def_id)),
                                "can't implement cross-crate trait for type in another crate"
                            ))
                        }
                    }
                    _ => {
                        Some((format!("cross-crate traits with a default impl, like `{}`, can \
                                       only be implemented for a struct/enum type, not `{}`",
                                      self.tcx.def_path_str(trait_def_id),
                                      self_ty),
                              "can't implement cross-crate trait with a default impl for \
                               non-struct/enum type"))
                    }
                };

                if let Some((msg, label)) = msg {
                    struct_span_err!(self.tcx.sess, sp, E0321, "{}", msg)
                        .span_label(sp, label)
                        .emit();
                    return;
                }
            }
        }
    }

    fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
    }

    fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
    }
}
