Skip to content

Commit

Permalink
Rollup merge of rust-lang#99345 - compiler-errors:issue-99073-redux, …
Browse files Browse the repository at this point in the history
…r=oli-obk

Do not allow typeck children items to constrain outer RPITs

Fixes rust-lang#99073 in a simpler and more conservative way than rust-lang#99079. Simply raise a mismatched types error if we try to constrain an RPIT in an item that isn't the RPIT's parent.

r? `@oli-obk`
  • Loading branch information
Dylan-DPC authored Jul 18, 2022
2 parents 0c612f3 + 273b977 commit 37e9c3f
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 1 deletion.
21 changes: 21 additions & 0 deletions compiler/rustc_borrowck/src/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
use rustc_infer::infer::{
InferCtxt, InferOk, LateBoundRegion, LateBoundRegionConversionTime, NllRegionVariableOrigin,
};
use rustc_infer::traits::ObligationCause;
use rustc_middle::mir::tcx::PlaceTy;
use rustc_middle::mir::visit::{NonMutatingUseContext, PlaceContext, Visitor};
use rustc_middle::mir::AssertKind;
Expand Down Expand Up @@ -224,6 +225,26 @@ pub(crate) fn type_check<'mir, 'tcx>(
)
.unwrap();
let mut hidden_type = infcx.resolve_vars_if_possible(decl.hidden_type);
// Check that RPITs are only constrained in their outermost
// function, otherwise report a mismatched types error.
if let OpaqueTyOrigin::FnReturn(parent) | OpaqueTyOrigin::AsyncFn(parent)
= infcx.opaque_ty_origin_unchecked(opaque_type_key.def_id, hidden_type.span)
&& parent.to_def_id() != body.source.def_id()
{
infcx
.report_mismatched_types(
&ObligationCause::misc(
hidden_type.span,
infcx.tcx.hir().local_def_id_to_hir_id(
body.source.def_id().expect_local(),
),
),
infcx.tcx.mk_opaque(opaque_type_key.def_id, opaque_type_key.substs),
hidden_type.ty,
ty::error::TypeError::Mismatch,
)
.emit();
}
trace!(
"finalized opaque type {:?} to {:#?}",
opaque_type_key,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
}

#[instrument(skip(self), level = "trace")]
fn opaque_ty_origin_unchecked(&self, opaque_def_id: DefId, span: Span) -> OpaqueTyOrigin {
pub fn opaque_ty_origin_unchecked(&self, opaque_def_id: DefId, span: Span) -> OpaqueTyOrigin {
let def_id = opaque_def_id.as_local().unwrap();
let origin = match self.tcx.hir().expect_item(def_id).kind {
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin,
Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/impl-trait/issue-99073-2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use std::fmt::Display;

fn main() {
test("hi", true);
}

fn test<T: Display>(t: T, recurse: bool) -> impl Display {
let f = || {
let i: u32 = test::<i32>(-1, false);
//~^ ERROR mismatched types
println!("{i}");
};
if recurse {
f();
}
t
}
15 changes: 15 additions & 0 deletions src/test/ui/impl-trait/issue-99073-2.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
error[E0308]: mismatched types
--> $DIR/issue-99073-2.rs:9:22
|
LL | fn test<T: Display>(t: T, recurse: bool) -> impl Display {
| ------------ the expected opaque type
LL | let f = || {
LL | let i: u32 = test::<i32>(-1, false);
| ^^^^^^^^^^^^^^^^^^^^^^ types differ
|
= note: expected opaque type `impl std::fmt::Display`
found type `u32`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.
8 changes: 8 additions & 0 deletions src/test/ui/impl-trait/issue-99073.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
fn main() {
let _ = fix(|_: &dyn Fn()| {});
}

fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
move || f(fix(&f))
//~^ ERROR mismatched types
}
14 changes: 14 additions & 0 deletions src/test/ui/impl-trait/issue-99073.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
error[E0308]: mismatched types
--> $DIR/issue-99073.rs:6:13
|
LL | fn fix<F: Fn(G), G: Fn()>(f: F) -> impl Fn() {
| --------- the expected opaque type
LL | move || f(fix(&f))
| ^^^^^^^^^^ types differ
|
= note: expected opaque type `impl Fn()`
found type parameter `G`

error: aborting due to previous error

For more information about this error, try `rustc --explain E0308`.

0 comments on commit 37e9c3f

Please sign in to comment.