})
}
+/// 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<DefId> {
+ 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.
// 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) => {
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);
+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<T>: '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`.
// 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<T>: 'static;
//~^ ERROR the parameter type `T` may not live long enough
+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<T>: 'static;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| - 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<T>: '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`.