diff --git a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs index f97dff146450..5707127340d8 100644 --- a/src/librustc_mir/borrow_check/type_check/free_region_relations.rs +++ b/src/librustc_mir/borrow_check/type_check/free_region_relations.rs @@ -259,7 +259,13 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> { .param_env .and(type_op::normalize::Normalize::new(ty)) .fully_perform(self.infcx) - .unwrap_or_else(|_| bug!("failed to normalize {:?}", ty)); + .unwrap_or_else(|_| { + self.infcx + .tcx + .sess + .delay_span_bug(DUMMY_SP, &format!("failed to normalize {:?}", ty)); + (self.infcx.tcx.types.err, None) + }); let constraints2 = self.add_implied_bounds(ty); normalized_inputs_and_output.push(ty); constraints1.into_iter().chain(constraints2) diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index 7d9bf975c691..8a83952c4fc7 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -806,7 +806,11 @@ fn check_where_clauses<'tcx, 'fcx>( let mut predicates = predicates.instantiate_identity(fcx.tcx); - if let Some((return_ty, span)) = return_ty { + if let Some((mut return_ty, span)) = return_ty { + if return_ty.has_infer_types_or_consts() { + fcx.select_obligations_where_possible(false, |_| {}); + return_ty = fcx.resolve_vars_if_possible(&return_ty); + } let opaque_types = check_opaque_types(tcx, fcx, def_id.expect_local(), span, return_ty); for _ in 0..opaque_types.len() { predicates.spans.push(span); @@ -893,10 +897,16 @@ fn check_opaque_types<'fcx, 'tcx>( trace!("check_opaque_types: opaque_ty, {:?}, {:?}", def_id, substs); let generics = tcx.generics_of(def_id); // Only check named `impl Trait` types defined in this crate. - // FIXME(eddyb) is `generics.parent.is_none()` correct? It seems - // potentially risky wrt associated types in `impl`s. - if generics.parent.is_none() && def_id.is_local() { + if !def_id.is_local() { + return ty; + } let opaque_hir_id = tcx.hir().as_local_hir_id(def_id.expect_local()); + if let hir::ItemKind::OpaqueTy(hir::OpaqueTy { impl_trait_fn: Some(_), .. }) = + tcx.hir().expect_item(opaque_hir_id).kind + { + // Don't check return position impl trait. + return ty; + } if may_define_opaque_type(tcx, fn_def_id, opaque_hir_id) { trace!("check_opaque_types: may define, generics={:#?}", generics); let mut seen_params: FxHashMap<_, Vec<_>> = FxHashMap::default(); @@ -924,9 +934,7 @@ fn check_opaque_types<'fcx, 'tcx>( true } - GenericArgKind::Const(ct) => { - matches!(ct.val, ty::ConstKind::Param(_)) - } + GenericArgKind::Const(ct) => matches!(ct.val, ty::ConstKind::Param(_)), }; if arg_is_param { @@ -988,7 +996,6 @@ fn check_opaque_types<'fcx, 'tcx>( substituted_predicates.push(substituted_pred); } } - } // if is_named_opaque_type } // if let Opaque ty }, diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs new file mode 100644 index 000000000000..bc6543a9229d --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.rs @@ -0,0 +1,18 @@ +// Ensure that we don't ICE if associated type impl trait is used in an impl +// with an unconstrained type parameter. + +#![feature(type_alias_impl_trait)] + +trait X { + type I; + fn f() -> Self::I; +} + +impl X for () { + type I = impl Sized; + //~^ ERROR could not find defining uses + fn f() -> Self::I {} + //~^ ERROR type annotations needed +} + +fn main() {} diff --git a/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr new file mode 100644 index 000000000000..e8b677113dba --- /dev/null +++ b/src/test/ui/type-alias-impl-trait/impl-with-unconstrained-param.stderr @@ -0,0 +1,15 @@ +error[E0282]: type annotations needed + --> $DIR/impl-with-unconstrained-param.rs:14:23 + | +LL | fn f() -> Self::I {} + | ^^ cannot infer type for type parameter `T` + +error: could not find defining uses + --> $DIR/impl-with-unconstrained-param.rs:12:14 + | +LL | type I = impl Sized; + | ^^^^^^^^^^ + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0282`. diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.rs b/src/test/ui/type-alias-impl-trait/issue-60564.rs index 4eb7f7836d86..78def0d1136d 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.rs +++ b/src/test/ui/type-alias-impl-trait/issue-60564.rs @@ -17,11 +17,8 @@ where { type BitsIter = IterBitsIter; fn iter_bits(self, n: u8) -> Self::BitsIter { - //~^ ERROR non-defining opaque type use in defining scope - //~| ERROR non-defining opaque type use in defining scope - (0u8..n) - .rev() - .map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) + //~^ ERROR non-defining opaque type use in defining scope + (0u8..n).rev().map(move |shift| ((self >> T::from(shift)) & T::from(1)).try_into().unwrap()) } } diff --git a/src/test/ui/type-alias-impl-trait/issue-60564.stderr b/src/test/ui/type-alias-impl-trait/issue-60564.stderr index 55984609437b..66fa862ef9d7 100644 --- a/src/test/ui/type-alias-impl-trait/issue-60564.stderr +++ b/src/test/ui/type-alias-impl-trait/issue-60564.stderr @@ -1,15 +1,3 @@ -error: non-defining opaque type use in defining scope - --> $DIR/issue-60564.rs:19:34 - | -LL | fn iter_bits(self, n: u8) -> Self::BitsIter { - | ^^^^^^^^^^^^^^ - | -note: used non-generic type `_` for generic parameter - --> $DIR/issue-60564.rs:8:22 - | -LL | type IterBitsIter = impl std::iter::Iterator; - | ^ - error: non-defining opaque type use in defining scope --> $DIR/issue-60564.rs:19:34 | @@ -22,5 +10,5 @@ note: used non-generic type `u8` for generic parameter LL | type IterBitsIter = impl std::iter::Iterator; | ^ -error: aborting due to 2 previous errors +error: aborting due to previous error