From: Oliver Schneider Date: Tue, 17 Jul 2018 11:44:42 +0000 (+0200) Subject: Prepare for using wfcheck on existential types X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=fdd719aa3df9bdbbd64b26ca12955605e57ea566;p=rust.git Prepare for using wfcheck on existential types --- diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7ae6f812649..178f0d3cdcb 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2856,22 +2856,26 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option }) } +/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition +pub fn is_impl_trait_defn(tcx: TyCtxt, def_id: DefId) -> Option { + if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { + if let hir::map::NodeItem(item) = tcx.hir.get(node_id) { + if let hir::ItemKind::Existential(ref exist_ty) = item.node { + return exist_ty.impl_trait_fn; + } + } + } + None +} + /// See `ParamEnv` struct def'n for details. fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ParamEnv<'tcx> { // The param_env of an impl Trait type is its defining function's param_env - if let Some(Def::Existential(_)) = tcx.describe_def(def_id) { - if let Some(node_id) = tcx.hir.as_local_node_id(def_id) { - if let hir::map::NodeItem(item) = tcx.hir.get(node_id) { - if let hir::ItemKind::Existential(ref exist_ty) = item.node { - if let Some(parent) = exist_ty.impl_trait_fn { - return param_env(tcx, parent); - } - } - } - } + if let Some(parent) = is_impl_trait_defn(tcx, def_id) { + return param_env(tcx, parent); } // Compute the bounds on Self and the type parameters. diff --git a/src/librustc/ty/wf.rs b/src/librustc/ty/wf.rs index 5376acca0d8..b99cdd59773 100644 --- a/src/librustc/ty/wf.rs +++ b/src/librustc/ty/wf.rs @@ -360,10 +360,16 @@ fn compute(&mut self, ty0: Ty<'tcx>) -> bool { // types appearing in the fn signature } - ty::TyAnon(..) => { + ty::TyAnon(did, substs) => { // all of the requirements on type parameters // should've been checked by the instantiation // of whatever returned this exact `impl Trait`. + + // for named existential types we still need to check them + if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() { + let obligations = self.nominal_obligations(did, substs); + self.out.extend(obligations); + } } ty::TyDynamic(data, r) => { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 60aea074f24..465faa1d477 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1037,15 +1037,9 @@ pub fn def_to_ty(&self, match path.def { Def::Existential(did) => { // check for desugared impl trait - if let Some(node_id) = tcx.hir.as_local_node_id(did) { - if let hir::map::NodeItem(item) = tcx.hir.get(node_id) { - if let hir::ItemKind::Existential(ref exist_ty) = item.node { - if exist_ty.impl_trait_fn.is_some() { - let lifetimes = &path.segments[0].args.as_ref().unwrap().args; - return self.impl_trait_ty_to_ty(did, lifetimes); - } - } - } + if ty::is_impl_trait_defn(tcx, did).is_some() { + let lifetimes = &path.segments[0].args.as_ref().unwrap().args; + return self.impl_trait_ty_to_ty(did, lifetimes); } let item_segment = path.segments.split_last().unwrap(); self.prohibit_generics(item_segment.1); diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr index 8a6cae08ce0..84af8e1dca2 100644 --- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr +++ b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.nll.stderr @@ -1,17 +1,18 @@ +error[E0308]: mismatched types + --> $DIR/generic_type_does_not_live_long_enough.rs:16:18 + | +LL | let z: i32 = x; //~ ERROR mismatched types + | ^ expected i32, found anonymized type + | + = note: expected type `i32` + found type `WrongGeneric::<&{integer}>` + warning: not reporting region error due to nll - --> $DIR/generic_type_does_not_live_long_enough.rs:16:1 + --> $DIR/generic_type_does_not_live_long_enough.rs:19:1 | LL | existential type WrongGeneric: 'static; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:20:5 - | -LL | t - | ^ - | - = help: consider adding an explicit lifetime bound `T: 'static`... - error: aborting due to previous error -For more information about this error, try `rustc --explain E0310`. +For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs index 092aa1eda16..440fc2d1284 100644 --- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs +++ b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs @@ -8,10 +8,13 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - #![feature(existential_type)] -fn main() {} +fn main() { + let y = 42; + let x = wrong_generic(&y); + let z: i32 = x; //~ ERROR mismatched types +} existential type WrongGeneric: 'static; //~^ ERROR the parameter type `T` may not live long enough diff --git a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr index cbf994defc8..189ad7d49a4 100644 --- a/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr +++ b/src/test/ui/existential_types/generic_type_does_not_live_long_enough.stderr @@ -1,5 +1,14 @@ +error[E0308]: mismatched types + --> $DIR/generic_type_does_not_live_long_enough.rs:16:18 + | +LL | let z: i32 = x; //~ ERROR mismatched types + | ^ expected i32, found anonymized type + | + = note: expected type `i32` + found type `WrongGeneric::<&{integer}>` + error[E0310]: the parameter type `T` may not live long enough - --> $DIR/generic_type_does_not_live_long_enough.rs:16:1 + --> $DIR/generic_type_does_not_live_long_enough.rs:19:1 | LL | existential type WrongGeneric: 'static; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,11 +17,12 @@ LL | fn wrong_generic(t: T) -> WrongGeneric { | - help: consider adding an explicit lifetime bound `T: 'static`... | note: ...so that the type `T` will meet its required lifetime bounds - --> $DIR/generic_type_does_not_live_long_enough.rs:16:1 + --> $DIR/generic_type_does_not_live_long_enough.rs:19:1 | LL | existential type WrongGeneric: 'static; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0310`. +Some errors occurred: E0308, E0310. +For more information about an error, try `rustc --explain E0308`.