diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 1f07e8f478b5a..ad6296e1a3bd8 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -893,6 +893,9 @@ impl<'a, 'tcx> CrateMetadata { EntryKind::AssociatedType(container) => { (ty::AssociatedKind::Type, container, false) } + EntryKind::AssociatedExistential(container) => { + (ty::AssociatedKind::Existential, container, false) + } _ => bug!("cannot get associated-item of `{:?}`", def_key) }; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 35616cc03a936..3db73800d640a 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -680,6 +680,7 @@ impl<'a> Resolver<'a> { } module.populated.set(true); } + Def::Existential(..) | Def::TraitAlias(..) => { self.define(parent, ident, TypeNS, (def, vis, DUMMY_SP, expansion)); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 53e44d53e6a9b..6cae8d6fc5b94 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -608,8 +608,8 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( if let ty::Opaque(def_id, substs) = ty.sty { trace!("check_existential_types: opaque_ty, {:?}, {:?}", def_id, substs); let generics = tcx.generics_of(def_id); - // only check named existential types - if generics.parent.is_none() { + // only check named existential types defined in this crate + if generics.parent.is_none() && def_id.is_local() { let opaque_node_id = tcx.hir().as_local_node_id(def_id).unwrap(); if may_define_existential_type(tcx, fn_def_id, opaque_node_id) { trace!("check_existential_types may define. Generics: {:#?}", generics); diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs new file mode 100644 index 0000000000000..af2d209826e19 --- /dev/null +++ b/src/test/ui/existential_types/auxiliary/cross_crate_ice.rs @@ -0,0 +1,12 @@ +// Crate that exports an existential type. Used for testing cross-crate. + +#![crate_type="rlib"] + +#![feature(existential_type)] + +pub existential type Foo: std::fmt::Debug; + +pub fn foo() -> Foo { + 5 +} + diff --git a/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs b/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs new file mode 100644 index 0000000000000..39ec5394febe4 --- /dev/null +++ b/src/test/ui/existential_types/auxiliary/cross_crate_ice2.rs @@ -0,0 +1,21 @@ +// Crate that exports an existential type. Used for testing cross-crate. + +#![crate_type="rlib"] + +#![feature(existential_type)] + +pub trait View { + type Tmp: Iterator; + + fn test(&self) -> Self::Tmp; +} + +pub struct X; + +impl View for X { + existential type Tmp: Iterator; + + fn test(&self) -> Self::Tmp { + vec![1,2,3].into_iter() + } +} diff --git a/src/test/ui/existential_types/cross_crate_ice.rs b/src/test/ui/existential_types/cross_crate_ice.rs new file mode 100644 index 0000000000000..c5d5ca916a48a --- /dev/null +++ b/src/test/ui/existential_types/cross_crate_ice.rs @@ -0,0 +1,16 @@ +// aux-build:cross_crate_ice.rs +// compile-pass + +extern crate cross_crate_ice; + +struct Bar(cross_crate_ice::Foo); + +impl Bar { + fn zero(&self) -> &cross_crate_ice::Foo { + &self.0 + } +} + +fn main() { + let _ = cross_crate_ice::foo(); +} diff --git a/src/test/ui/existential_types/cross_crate_ice2.rs b/src/test/ui/existential_types/cross_crate_ice2.rs new file mode 100644 index 0000000000000..a0f3933ce33b2 --- /dev/null +++ b/src/test/ui/existential_types/cross_crate_ice2.rs @@ -0,0 +1,11 @@ +// aux-build:cross_crate_ice2.rs +// compile-pass + +extern crate cross_crate_ice2; + +use cross_crate_ice2::View; + +fn main() { + let v = cross_crate_ice2::X; + v.test(); +}