Skip to content

Commit fdd719a

Browse files
committed
Prepare for using wfcheck on existential types
1 parent feb139f commit fdd719a

File tree

6 files changed

+54
-36
lines changed

6 files changed

+54
-36
lines changed

src/librustc/ty/mod.rs

+14-10
Original file line numberDiff line numberDiff line change
@@ -2856,22 +2856,26 @@ fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option
28562856
})
28572857
}
28582858

2859+
/// Yields the parent function's `DefId` if `def_id` is an `impl Trait` definition
2860+
pub fn is_impl_trait_defn(tcx: TyCtxt, def_id: DefId) -> Option<DefId> {
2861+
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
2862+
if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
2863+
if let hir::ItemKind::Existential(ref exist_ty) = item.node {
2864+
return exist_ty.impl_trait_fn;
2865+
}
2866+
}
2867+
}
2868+
None
2869+
}
2870+
28592871
/// See `ParamEnv` struct def'n for details.
28602872
fn param_env<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
28612873
def_id: DefId)
28622874
-> ParamEnv<'tcx> {
28632875

28642876
// The param_env of an impl Trait type is its defining function's param_env
2865-
if let Some(Def::Existential(_)) = tcx.describe_def(def_id) {
2866-
if let Some(node_id) = tcx.hir.as_local_node_id(def_id) {
2867-
if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
2868-
if let hir::ItemKind::Existential(ref exist_ty) = item.node {
2869-
if let Some(parent) = exist_ty.impl_trait_fn {
2870-
return param_env(tcx, parent);
2871-
}
2872-
}
2873-
}
2874-
}
2877+
if let Some(parent) = is_impl_trait_defn(tcx, def_id) {
2878+
return param_env(tcx, parent);
28752879
}
28762880
// Compute the bounds on Self and the type parameters.
28772881

src/librustc/ty/wf.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -360,10 +360,16 @@ impl<'a, 'gcx, 'tcx> WfPredicates<'a, 'gcx, 'tcx> {
360360
// types appearing in the fn signature
361361
}
362362

363-
ty::TyAnon(..) => {
363+
ty::TyAnon(did, substs) => {
364364
// all of the requirements on type parameters
365365
// should've been checked by the instantiation
366366
// of whatever returned this exact `impl Trait`.
367+
368+
// for named existential types we still need to check them
369+
if super::is_impl_trait_defn(self.infcx.tcx, did).is_none() {
370+
let obligations = self.nominal_obligations(did, substs);
371+
self.out.extend(obligations);
372+
}
367373
}
368374

369375
ty::TyDynamic(data, r) => {

src/librustc_typeck/astconv.rs

+3-9
Original file line numberDiff line numberDiff line change
@@ -1037,15 +1037,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx>+'o {
10371037
match path.def {
10381038
Def::Existential(did) => {
10391039
// check for desugared impl trait
1040-
if let Some(node_id) = tcx.hir.as_local_node_id(did) {
1041-
if let hir::map::NodeItem(item) = tcx.hir.get(node_id) {
1042-
if let hir::ItemKind::Existential(ref exist_ty) = item.node {
1043-
if exist_ty.impl_trait_fn.is_some() {
1044-
let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
1045-
return self.impl_trait_ty_to_ty(did, lifetimes);
1046-
}
1047-
}
1048-
}
1040+
if ty::is_impl_trait_defn(tcx, did).is_some() {
1041+
let lifetimes = &path.segments[0].args.as_ref().unwrap().args;
1042+
return self.impl_trait_ty_to_ty(did, lifetimes);
10491043
}
10501044
let item_segment = path.segments.split_last().unwrap();
10511045
self.prohibit_generics(item_segment.1);
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/generic_type_does_not_live_long_enough.rs:16:18
3+
|
4+
LL | let z: i32 = x; //~ ERROR mismatched types
5+
| ^ expected i32, found anonymized type
6+
|
7+
= note: expected type `i32`
8+
found type `WrongGeneric::<&{integer}>`
9+
110
warning: not reporting region error due to nll
2-
--> $DIR/generic_type_does_not_live_long_enough.rs:16:1
11+
--> $DIR/generic_type_does_not_live_long_enough.rs:19:1
312
|
413
LL | existential type WrongGeneric<T>: 'static;
514
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
615

7-
error[E0310]: the parameter type `T` may not live long enough
8-
--> $DIR/generic_type_does_not_live_long_enough.rs:20:5
9-
|
10-
LL | t
11-
| ^
12-
|
13-
= help: consider adding an explicit lifetime bound `T: 'static`...
14-
1516
error: aborting due to previous error
1617

17-
For more information about this error, try `rustc --explain E0310`.
18+
For more information about this error, try `rustc --explain E0308`.

src/test/ui/existential_types/generic_type_does_not_live_long_enough.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
1211
#![feature(existential_type)]
1312

14-
fn main() {}
13+
fn main() {
14+
let y = 42;
15+
let x = wrong_generic(&y);
16+
let z: i32 = x; //~ ERROR mismatched types
17+
}
1518

1619
existential type WrongGeneric<T>: 'static;
1720
//~^ ERROR the parameter type `T` may not live long enough
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/generic_type_does_not_live_long_enough.rs:16:18
3+
|
4+
LL | let z: i32 = x; //~ ERROR mismatched types
5+
| ^ expected i32, found anonymized type
6+
|
7+
= note: expected type `i32`
8+
found type `WrongGeneric::<&{integer}>`
9+
110
error[E0310]: the parameter type `T` may not live long enough
2-
--> $DIR/generic_type_does_not_live_long_enough.rs:16:1
11+
--> $DIR/generic_type_does_not_live_long_enough.rs:19:1
312
|
413
LL | existential type WrongGeneric<T>: 'static;
514
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,11 +17,12 @@ LL | fn wrong_generic<T>(t: T) -> WrongGeneric<T> {
817
| - help: consider adding an explicit lifetime bound `T: 'static`...
918
|
1019
note: ...so that the type `T` will meet its required lifetime bounds
11-
--> $DIR/generic_type_does_not_live_long_enough.rs:16:1
20+
--> $DIR/generic_type_does_not_live_long_enough.rs:19:1
1221
|
1322
LL | existential type WrongGeneric<T>: 'static;
1423
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1524

16-
error: aborting due to previous error
25+
error: aborting due to 2 previous errors
1726

18-
For more information about this error, try `rustc --explain E0310`.
27+
Some errors occurred: E0308, E0310.
28+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)