fldop: |ty| {
if let ty::TyAnon(def_id, substs) = ty.sty {
trace!("check_existential_types: anon_ty, {:?}, {:?}", def_id, substs);
- let anon_node_id = tcx.hir.as_local_node_id(def_id).unwrap();
- if may_define_existential_type(tcx, fn_def_id, anon_node_id) {
- let generics = tcx.generics_of(def_id);
- trace!("check_existential_types may define. Generics: {:#?}", generics);
- for (subst, param) in substs.iter().zip(&generics.params) {
- if let ty::subst::UnpackedKind::Type(ty) = subst.unpack() {
- match ty.sty {
- ty::TyParam(..) => {},
- // prevent `fn foo() -> Foo<u32>` from being defining
- _ => {
- tcx
- .sess
- .struct_span_err(
- span,
- "non-defining existential type use in defining scope",
- )
- .span_note(
- tcx.def_span(param.def_id),
- &format!(
- "used non-generic type {} for generic parameter",
- ty,
- ),
- )
- .emit();
- return tcx.types.err;
- },
- } // match ty
- } // if let Type = subst
- } // for (subst, param)
- } // if may_define_existential_type
-
- // now register the bounds on the parameters of the existential type
- // so the parameters given by the function need to fulfil them
- // ```rust
- // existential type Foo<T: Bar>: 'static;
- // fn foo<U>() -> Foo<U> { .. *}
- // ```
- // becomes
- // ```rust
- // existential type Foo<T: Bar>: 'static;
- // fn foo<U: Bar>() -> Foo<U> { .. *}
- // ```
- let predicates = tcx.predicates_of(def_id);
- trace!("check_existential_types may define. adding predicates: {:#?}", predicates);
- for &pred in predicates.predicates.iter() {
- let substituted_pred = pred.subst(fcx.tcx, substs);
- // Avoid duplication of predicates that contain no parameters, for example.
- if !predicates.predicates.contains(&substituted_pred) {
- substituted_predicates.push(substituted_pred);
+ let generics = tcx.generics_of(def_id);
+ // only check named existential types
+ if generics.parent.is_none() {
+ let anon_node_id = tcx.hir.as_local_node_id(def_id).unwrap();
+ if may_define_existential_type(tcx, fn_def_id, anon_node_id) {
+ trace!("check_existential_types may define. Generics: {:#?}", generics);
+ for (subst, param) in substs.iter().zip(&generics.params) {
+ if let ty::subst::UnpackedKind::Type(ty) = subst.unpack() {
+ match ty.sty {
+ ty::TyParam(..) => {},
+ // prevent `fn foo() -> Foo<u32>` from being defining
+ _ => {
+ tcx
+ .sess
+ .struct_span_err(
+ span,
+ "non-defining existential type use \
+ in defining scope",
+ )
+ .span_note(
+ tcx.def_span(param.def_id),
+ &format!(
+ "used non-generic type {} for \
+ generic parameter",
+ ty,
+ ),
+ )
+ .emit();
+ return tcx.types.err;
+ },
+ } // match ty
+ } // if let Type = subst
+ } // for (subst, param)
+ } // if may_define_existential_type
+
+ // now register the bounds on the parameters of the existential type
+ // so the parameters given by the function need to fulfil them
+ // ```rust
+ // existential type Foo<T: Bar>: 'static;
+ // fn foo<U>() -> Foo<U> { .. *}
+ // ```
+ // becomes
+ // ```rust
+ // existential type Foo<T: Bar>: 'static;
+ // fn foo<U: Bar>() -> Foo<U> { .. *}
+ // ```
+ let predicates = tcx.predicates_of(def_id);
+ trace!(
+ "check_existential_types may define. adding predicates: {:#?}",
+ predicates,
+ );
+ for &pred in predicates.predicates.iter() {
+ let substituted_pred = pred.subst(fcx.tcx, substs);
+ // Avoid duplication of predicates that contain no parameters, for example.
+ if !predicates.predicates.contains(&substituted_pred) {
+ substituted_predicates.push(substituted_pred);
+ }
}
- }
+ } // if is_named_existential_type
} // if let TyAnon
ty
},