Skip to content

Commit b87e8ea

Browse files
committed
Check associated opaque types in check_opaque_types
1 parent 50c0192 commit b87e8ea

File tree

6 files changed

+58
-27
lines changed

6 files changed

+58
-27
lines changed

src/librustc_mir/borrow_check/type_check/free_region_relations.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,13 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
259259
.param_env
260260
.and(type_op::normalize::Normalize::new(ty))
261261
.fully_perform(self.infcx)
262-
.unwrap_or_else(|_| bug!("failed to normalize {:?}", ty));
262+
.unwrap_or_else(|_| {
263+
self.infcx
264+
.tcx
265+
.sess
266+
.delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty));
267+
(self.infcx.tcx.types.err, None)
268+
});
263269
let constraints2 = self.add_implied_bounds(ty);
264270
normalized_inputs_and_output.push(ty);
265271
constraints1.into_iter().chain(constraints2)

src/librustc_typeck/check/wfcheck.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -806,7 +806,11 @@ fn check_where_clauses<'tcx, 'fcx>(
806806

807807
let mut predicates = predicates.instantiate_identity(fcx.tcx);
808808

809-
if let Some((return_ty, span)) = return_ty {
809+
if let Some((mut return_ty, span)) = return_ty {
810+
if return_ty.has_infer_types_or_consts() {
811+
fcx.select_obligations_where_possible(false, |_| {});
812+
return_ty = fcx.resolve_vars_if_possible(&return_ty);
813+
}
810814
let opaque_types = check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty);
811815
for _ in 0..opaque_types.len() {
812816
predicates.spans.push(span);
@@ -893,10 +897,16 @@ fn check_opaque_types<'fcx, 'tcx>(
893897
trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs);
894898
let generics = tcx.generics_of(def_id);
895899
// Only check named `impl Trait` types defined in this crate.
896-
// FIXME(eddyb) is `generics.parent.is_none()` correct? It seems
897-
// potentially risky wrt associated types in `impl`s.
898-
if generics.parent.is_none() && def_id.is_local() {
900+
if !def_id.is_local() {
901+
return ty;
902+
}
899903
let opaque_hir_id = tcx.hir().as_local_hir_id(def_id.expect_local());
904+
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) =
905+
tcx.hir().expect_item(opaque_hir_id).kind
906+
{
907+
// Don't check return position impl trait.
908+
return ty;
909+
}
900910
if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) {
901911
trace!("check_opaque_types: may define, generics={:#?}", generics);
902912
let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default();
@@ -924,9 +934,7 @@ fn check_opaque_types<'fcx, 'tcx>(
924934
true
925935
}
926936

927-
GenericArgKind::Const(ct) => {
928-
matches!(ct.val, ty::ConstKind::Param(_))
929-
}
937+
GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)),
930938
};
931939

932940
if arg_is_param {
@@ -988,7 +996,6 @@ fn check_opaque_types<'fcx, 'tcx>(
988996
substituted_predicates.push(substituted_pred);
989997
}
990998
}
991-
} // if is_named_opaque_type
992999
} // if let Opaque
9931000
ty
9941001
},
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// Ensure that we don't ICE if associated type impl trait is used in an impl
2+
// with an unconstrained type parameter.
3+
4+
#![feature(type_alias_impl_trait)]
5+
6+
trait X {
7+
type I;
8+
fn f() -> Self::I;
9+
}
10+
11+
impl<T> X for () {
12+
type I = impl Sized;
13+
//~^ ERROR could not find defining uses
14+
fn f() -> Self::I {}
15+
//~^ ERROR type annotations needed
16+
}
17+
18+
fn main() {}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
error[E0282]: type annotations needed
2+
--> $DIR/impl-with-unconstrained-param.rs:14:23
3+
|
4+
LL | fn f() -> Self::I {}
5+
| ^^ cannot infer type for type parameter `T`
6+
7+
error: could not find defining uses
8+
--> $DIR/impl-with-unconstrained-param.rs:12:14
9+
|
10+
LL | type I = impl Sized;
11+
| ^^^^^^^^^^
12+
13+
error: aborting due to 2 previous errors
14+
15+
For more information about this error, try `rustc --explain E0282`.

src/test/ui/type-alias-impl-trait/issue-60564.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,8 @@ where
1717
{
1818
type BitsIter = IterBitsIter<T, E, u8>;
1919
fn iter_bits(self, n: u8) -> Self::BitsIter {
20-
//~^ ERROR non-defining opaque type use in defining scope
21-
//~| ERROR non-defining opaque type use in defining scope
22-
(0u8..n)
23-
.rev()
24-
.map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
20+
//~^ ERROR non-defining opaque type use in defining scope
21+
(0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap())
2522
}
2623
}
2724

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,3 @@
1-
error: non-defining opaque type use in defining scope
2-
--> $DIR/issue-60564.rs:19:34
3-
|
4-
LL | fn iter_bits(self, n: u8) -> Self::BitsIter {
5-
| ^^^^^^^^^^^^^^
6-
|
7-
note: used non-generic type `_` for generic parameter
8-
--> $DIR/issue-60564.rs:8:22
9-
|
10-
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
11-
| ^
12-
131
error: non-defining opaque type use in defining scope
142
--> $DIR/issue-60564.rs:19:34
153
|
@@ -22,5 +10,5 @@ note: used non-generic type `u8` for generic parameter
2210
LL | type IterBitsIter<T, E, I> = impl std::iter::Iterator<Item = I>;
2311
| ^
2412

25-
error: aborting due to 2 previous errors
13+
error: aborting due to previous error
2614

0 commit comments

Comments
 (0)