From 2ed1aca101d449bb24d607ffbe436511e999573d Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 16 Jul 2018 10:46:27 +0200 Subject: [PATCH] Only check existential types, not the desugared impl Trait --- src/librustc_typeck/check/wfcheck.rs | 108 ++++++++++++++------------- 1 file changed, 58 insertions(+), 50 deletions(-) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index df8323f8513..d2c96221991 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -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` 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: 'static; - // fn foo() -> Foo { .. *} - // ``` - // becomes - // ```rust - // existential type Foo: 'static; - // fn foo() -> Foo { .. *} - // ``` - 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` 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: 'static; + // fn foo() -> Foo { .. *} + // ``` + // becomes + // ```rust + // existential type Foo: 'static; + // fn foo() -> Foo { .. *} + // ``` + 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 }, -- 2.44.0