mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Rollup merge of #99345 - compiler-errors:issue-99073-redux, r=oli-obk
Do not allow typeck children items to constrain outer RPITs Fixes #99073 in a simpler and more conservative way than #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`
This commit is contained in:
commit
3c3c5da9ad
@ -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;
|
||||
@ -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.to_def_id(), opaque_type_key.substs),
|
||||
hidden_type.ty,
|
||||
ty::error::TypeError::Mismatch,
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
trace!(
|
||||
"finalized opaque type {:?} to {:#?}",
|
||||
opaque_type_key,
|
||||
|
@ -433,7 +433,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[instrument(skip(self), level = "trace")]
|
||||
fn opaque_ty_origin_unchecked(&self, def_id: LocalDefId, span: Span) -> OpaqueTyOrigin {
|
||||
pub fn opaque_ty_origin_unchecked(&self, def_id: LocalDefId, span: Span) -> OpaqueTyOrigin {
|
||||
let origin = match self.tcx.hir().expect_item(def_id).kind {
|
||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => origin,
|
||||
ref itemkind => {
|
||||
|
17
src/test/ui/impl-trait/issue-99073-2.rs
Normal file
17
src/test/ui/impl-trait/issue-99073-2.rs
Normal file
@ -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
src/test/ui/impl-trait/issue-99073-2.stderr
Normal file
15
src/test/ui/impl-trait/issue-99073-2.stderr
Normal file
@ -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
src/test/ui/impl-trait/issue-99073.rs
Normal file
8
src/test/ui/impl-trait/issue-99073.rs
Normal file
@ -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
src/test/ui/impl-trait/issue-99073.stderr
Normal file
14
src/test/ui/impl-trait/issue-99073.stderr
Normal file
@ -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`.
|
Loading…
Reference in New Issue
Block a user