]> git.lizzy.rs Git - rust.git/commitdiff
Only check existential types, not the desugared impl Trait
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Mon, 16 Jul 2018 08:46:27 +0000 (10:46 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Wed, 18 Jul 2018 08:53:08 +0000 (10:53 +0200)
src/librustc_typeck/check/wfcheck.rs

index df8323f85132bafb9a85634184924b45e2a238bb..d2c96221991600637b337d26bfd21afd85cc1eda 100644 (file)
@@ -549,57 +549,65 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>(
         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
         },