Skip to content

Commit 7c0fb38

Browse files
committedJul 20, 2022
take opaq types
1 parent 03d488b commit 7c0fb38

18 files changed

+292
-184
lines changed
 

‎compiler/rustc_borrowck/src/consumers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use rustc_hir::def_id::LocalDefId;
44
use rustc_index::vec::IndexVec;
5-
use rustc_infer::infer::TyCtxtInferExt;
5+
use rustc_infer::infer::{DefiningAnchor, TyCtxtInferExt};
66
use rustc_middle::mir::Body;
77
use rustc_middle::ty::{self, TyCtxt};
88

@@ -31,7 +31,7 @@ pub fn get_body_with_borrowck_facts<'tcx>(
3131
def: ty::WithOptConstParam<LocalDefId>,
3232
) -> BodyWithBorrowckFacts<'tcx> {
3333
let (input_body, promoted) = tcx.mir_promoted(def);
34-
tcx.infer_ctxt().with_opaque_type_inference(def.did).enter(|infcx| {
34+
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(def.did)).enter(|infcx| {
3535
let input_body: &Body<'_> = &input_body.borrow();
3636
let promoted: &IndexVec<_, _> = &promoted.borrow();
3737
*super::do_mir_borrowck(&infcx, input_body, promoted, true).1.unwrap()

‎compiler/rustc_borrowck/src/lib.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use rustc_hir as hir;
2424
use rustc_hir::def_id::LocalDefId;
2525
use rustc_index::bit_set::ChunkedBitSet;
2626
use rustc_index::vec::IndexVec;
27-
use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
27+
use rustc_infer::infer::{DefiningAnchor, InferCtxt, TyCtxtInferExt};
2828
use rustc_middle::mir::{
2929
traversal, Body, ClearCrossCrate, Local, Location, Mutability, Operand, Place, PlaceElem,
3030
PlaceRef, VarDebugInfoContents,
@@ -130,11 +130,14 @@ fn mir_borrowck<'tcx>(
130130
debug!("run query mir_borrowck: {}", tcx.def_path_str(def.did.to_def_id()));
131131
let hir_owner = tcx.hir().local_def_id_to_hir_id(def.did).owner;
132132

133-
let opt_closure_req = tcx.infer_ctxt().with_opaque_type_inference(hir_owner).enter(|infcx| {
134-
let input_body: &Body<'_> = &input_body.borrow();
135-
let promoted: &IndexVec<_, _> = &promoted.borrow();
136-
do_mir_borrowck(&infcx, input_body, promoted, false).0
137-
});
133+
let opt_closure_req = tcx
134+
.infer_ctxt()
135+
.with_opaque_type_inference(DefiningAnchor::Bind(hir_owner))
136+
.enter(|infcx| {
137+
let input_body: &Body<'_> = &input_body.borrow();
138+
let promoted: &IndexVec<_, _> = &promoted.borrow();
139+
do_mir_borrowck(&infcx, input_body, promoted, false).0
140+
});
138141
debug!("mir_borrowck done");
139142

140143
tcx.arena.alloc(opt_closure_req)

‎compiler/rustc_borrowck/src/region_infer/opaque_types.rs

Lines changed: 54 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use rustc_data_structures::vec_map::VecMap;
33
use rustc_hir::def_id::LocalDefId;
44
use rustc_hir::OpaqueTyOrigin;
55
use rustc_infer::infer::error_reporting::unexpected_hidden_region_diagnostic;
6-
use rustc_infer::infer::InferCtxt;
76
use rustc_infer::infer::TyCtxtInferExt as _;
7+
use rustc_infer::infer::{DefiningAnchor, InferCtxt};
88
use rustc_infer::traits::{Obligation, ObligationCause, TraitEngine};
99
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
1010
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, InternalSubsts};
@@ -269,59 +269,65 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
269269
// FIXME(oli-obk): Also do region checks here and then consider removing `check_opaque_meets_bounds` entirely.
270270
let param_env = self.tcx.param_env(def_id);
271271
let body_id = self.tcx.local_def_id_to_hir_id(def_id);
272-
self.tcx.infer_ctxt().enter(move |infcx| {
273-
// Require the hidden type to be well-formed with only the generics of the opaque type.
274-
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
275-
// hidden type is well formed even without those bounds.
276-
let predicate =
277-
ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
278-
.to_predicate(infcx.tcx);
279-
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
280-
281-
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
282-
// the bounds that the function supplies.
283-
match infcx.register_hidden_type(
284-
OpaqueTypeKey { def_id, substs: id_substs },
285-
ObligationCause::misc(instantiated_ty.span, body_id),
286-
param_env,
287-
definition_ty,
288-
origin,
289-
) {
290-
Ok(infer_ok) => {
291-
for obligation in infer_ok.obligations {
292-
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
272+
// HACK This bubble is required for this tests to pass:
273+
// type-alias-impl-trait/issue-67844-nested-opaque.rs
274+
self.tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(
275+
move |infcx| {
276+
// Require the hidden type to be well-formed with only the generics of the opaque type.
277+
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
278+
// hidden type is well formed even without those bounds.
279+
let predicate =
280+
ty::Binder::dummy(ty::PredicateKind::WellFormed(definition_ty.into()))
281+
.to_predicate(infcx.tcx);
282+
let mut fulfillment_cx = <dyn TraitEngine<'tcx>>::new(infcx.tcx);
283+
284+
// Require that the hidden type actually fulfills all the bounds of the opaque type, even without
285+
// the bounds that the function supplies.
286+
match infcx.register_hidden_type(
287+
OpaqueTypeKey { def_id, substs: id_substs },
288+
ObligationCause::misc(instantiated_ty.span, body_id),
289+
param_env,
290+
definition_ty,
291+
origin,
292+
) {
293+
Ok(infer_ok) => {
294+
for obligation in infer_ok.obligations {
295+
fulfillment_cx.register_predicate_obligation(&infcx, obligation);
296+
}
297+
}
298+
Err(err) => {
299+
infcx
300+
.report_mismatched_types(
301+
&ObligationCause::misc(instantiated_ty.span, body_id),
302+
self.tcx.mk_opaque(def_id, id_substs),
303+
definition_ty,
304+
err,
305+
)
306+
.emit();
293307
}
294308
}
295-
Err(err) => {
296-
infcx
297-
.report_mismatched_types(
298-
&ObligationCause::misc(instantiated_ty.span, body_id),
299-
self.tcx.mk_opaque(def_id.to_def_id(), id_substs),
300-
definition_ty,
301-
err,
302-
)
303-
.emit();
304-
}
305-
}
306309

307-
fulfillment_cx.register_predicate_obligation(
308-
&infcx,
309-
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
310-
);
310+
fulfillment_cx.register_predicate_obligation(
311+
&infcx,
312+
Obligation::misc(instantiated_ty.span, body_id, param_env, predicate),
313+
);
311314

312-
// Check that all obligations are satisfied by the implementation's
313-
// version.
314-
let errors = fulfillment_cx.select_all_or_error(&infcx);
315+
// Check that all obligations are satisfied by the implementation's
316+
// version.
317+
let errors = fulfillment_cx.select_all_or_error(&infcx);
315318

316-
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
319+
// This is still required for many(half of the tests in ui/type-alias-impl-trait)
320+
// tests to pass
321+
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
317322

318-
if errors.is_empty() {
319-
definition_ty
320-
} else {
321-
infcx.report_fulfillment_errors(&errors, None, false);
322-
self.tcx.ty_error()
323-
}
324-
})
323+
if errors.is_empty() {
324+
definition_ty
325+
} else {
326+
infcx.report_fulfillment_errors(&errors, None, false);
327+
self.tcx.ty_error()
328+
}
329+
},
330+
)
325331
} else {
326332
definition_ty
327333
}

‎compiler/rustc_infer/src/infer/mod.rs

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -239,17 +239,31 @@ impl<'tcx> InferCtxtInner<'tcx> {
239239
}
240240
}
241241

242+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
243+
pub enum DefiningAnchor {
244+
/// `DefId` of the item.
245+
Bind(LocalDefId),
246+
/// When opaque types are not resolved, we `Bubble` up, meaning
247+
/// return the opaque/hidden type pair from query, for caller of query to handle it.
248+
Bubble,
249+
/// Used to catch type mismatch errors when handling opaque types.
250+
Error,
251+
}
252+
242253
pub struct InferCtxt<'a, 'tcx> {
243254
pub tcx: TyCtxt<'tcx>,
244255

245256
/// The `DefId` of the item in whose context we are performing inference or typeck.
246257
/// It is used to check whether an opaque type use is a defining use.
247258
///
248-
/// If it is `None`, we can't resolve opaque types here and need to bubble up
259+
/// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
249260
/// the obligation. This frequently happens for
250261
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
251262
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
252-
pub defining_use_anchor: Option<LocalDefId>,
263+
///
264+
/// It is default value is `DefiningAnchor::Error`, this way it is easier to catch errors that
265+
/// might come up during inference or typeck.
266+
pub defining_use_anchor: DefiningAnchor,
253267

254268
/// During type-checking/inference of a body, `in_progress_typeck_results`
255269
/// contains a reference to the typeck results being built up, which are
@@ -526,7 +540,7 @@ impl<'tcx> fmt::Display for FixupError<'tcx> {
526540
pub struct InferCtxtBuilder<'tcx> {
527541
tcx: TyCtxt<'tcx>,
528542
fresh_typeck_results: Option<RefCell<ty::TypeckResults<'tcx>>>,
529-
defining_use_anchor: Option<LocalDefId>,
543+
defining_use_anchor: DefiningAnchor,
530544
}
531545

532546
pub trait TyCtxtInferExt<'tcx> {
@@ -535,7 +549,11 @@ pub trait TyCtxtInferExt<'tcx> {
535549

536550
impl<'tcx> TyCtxtInferExt<'tcx> for TyCtxt<'tcx> {
537551
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
538-
InferCtxtBuilder { tcx: self, defining_use_anchor: None, fresh_typeck_results: None }
552+
InferCtxtBuilder {
553+
tcx: self,
554+
defining_use_anchor: DefiningAnchor::Error,
555+
fresh_typeck_results: None,
556+
}
539557
}
540558
}
541559

@@ -545,7 +563,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
545563
/// Will also change the scope for opaque type defining use checks to the given owner.
546564
pub fn with_fresh_in_progress_typeck_results(mut self, table_owner: LocalDefId) -> Self {
547565
self.fresh_typeck_results = Some(RefCell::new(ty::TypeckResults::new(table_owner)));
548-
self.with_opaque_type_inference(table_owner)
566+
self.with_opaque_type_inference(DefiningAnchor::Bind(table_owner))
549567
}
550568

551569
/// Whenever the `InferCtxt` should be able to handle defining uses of opaque types,
@@ -554,8 +572,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
554572
/// It is only meant to be called in two places, for typeck
555573
/// (via `with_fresh_in_progress_typeck_results`) and for the inference context used
556574
/// in mir borrowck.
557-
pub fn with_opaque_type_inference(mut self, defining_use_anchor: LocalDefId) -> Self {
558-
self.defining_use_anchor = Some(defining_use_anchor);
575+
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor) -> Self {
576+
self.defining_use_anchor = defining_use_anchor;
559577
self
560578
}
561579

‎compiler/rustc_infer/src/infer/opaque_types.rs

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::infer::{InferCtxt, InferOk};
1+
use crate::infer::{DefiningAnchor, InferCtxt, InferOk};
22
use crate::traits;
33
use hir::def_id::{DefId, LocalDefId};
44
use hir::{HirId, OpaqueTyOrigin};
@@ -101,44 +101,46 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
101101
let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() {
102102
ty::Opaque(def_id, substs) if def_id.is_local() => {
103103
let def_id = def_id.expect_local();
104-
let origin = if self.defining_use_anchor.is_some() {
105-
// Check that this is `impl Trait` type is
106-
// declared by `parent_def_id` -- i.e., one whose
107-
// value we are inferring. At present, this is
108-
// always true during the first phase of
109-
// type-check, but not always true later on during
110-
// NLL. Once we support named opaque types more fully,
111-
// this same scenario will be able to arise during all phases.
112-
//
113-
// Here is an example using type alias `impl Trait`
114-
// that indicates the distinction we are checking for:
115-
//
116-
// ```rust
117-
// mod a {
118-
// pub type Foo = impl Iterator;
119-
// pub fn make_foo() -> Foo { .. }
120-
// }
121-
//
122-
// mod b {
123-
// fn foo() -> a::Foo { a::make_foo() }
124-
// }
125-
// ```
126-
//
127-
// Here, the return type of `foo` references an
128-
// `Opaque` indeed, but not one whose value is
129-
// presently being inferred. You can get into a
130-
// similar situation with closure return types
131-
// today:
132-
//
133-
// ```rust
134-
// fn foo() -> impl Iterator { .. }
135-
// fn bar() {
136-
// let x = || foo(); // returns the Opaque assoc with `foo`
137-
// }
138-
// ```
139-
self.opaque_type_origin(def_id, cause.span)?
140-
} else {
141-
self.opaque_ty_origin_unchecked(def_id, cause.span)
104+
let origin = match self.defining_use_anchor {
105+
DefiningAnchor::Bind(_) => {
106+
// Check that this is `impl Trait` type is
107+
// declared by `parent_def_id` -- i.e., one whose
108+
// value we are inferring. At present, this is
109+
// always true during the first phase of
110+
// type-check, but not always true later on during
111+
// NLL. Once we support named opaque types more fully,
112+
// this same scenario will be able to arise during all phases.
113+
//
114+
// Here is an example using type alias `impl Trait`
115+
// that indicates the distinction we are checking for:
116+
//
117+
// ```rust
118+
// mod a {
119+
// pub type Foo = impl Iterator;
120+
// pub fn make_foo() -> Foo { .. }
121+
// }
122+
//
123+
// mod b {
124+
// fn foo() -> a::Foo { a::make_foo() }
125+
// }
126+
// ```
127+
//
128+
// Here, the return type of `foo` references an
129+
// `Opaque` indeed, but not one whose value is
130+
// presently being inferred. You can get into a
131+
// similar situation with closure return types
132+
// today:
133+
//
134+
// ```rust
135+
// fn foo() -> impl Iterator { .. }
136+
// fn bar() {
137+
// let x = || foo(); // returns the Opaque assoc with `foo`
138+
// }
139+
// ```
140+
self.opaque_type_origin(def_id, cause.span)?
141+
}
142+
DefiningAnchor::Bubble => self.opaque_ty_origin_unchecked(def_id, cause.span),
143+
DefiningAnchor::Error => return None,
142144
};
143145
if let ty::Opaque(did2, _) = *b.kind() {
144146
// We could accept this, but there are various ways to handle this situation, and we don't
@@ -407,7 +409,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
407409
#[instrument(skip(self), level = "trace")]
408410
pub fn opaque_type_origin(&self, def_id: LocalDefId, span: Span) -> Option<OpaqueTyOrigin> {
409411
let opaque_hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id);
410-
let parent_def_id = self.defining_use_anchor?;
412+
let parent_def_id = match self.defining_use_anchor {
413+
DefiningAnchor::Bubble | DefiningAnchor::Error => return None,
414+
DefiningAnchor::Bind(bind) => bind,
415+
};
411416
let item_kind = &self.tcx.hir().expect_item(def_id).kind;
412417

413418
let hir::ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) = item_kind else {

‎compiler/rustc_trait_selection/src/traits/codegen.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// seems likely that they should eventually be merged into more
44
// general routines.
55

6-
use crate::infer::TyCtxtInferExt;
6+
use crate::infer::{DefiningAnchor, TyCtxtInferExt};
77
use crate::traits::{
88
FulfillmentContext, ImplSource, Obligation, ObligationCause, SelectionContext, TraitEngine,
99
Unimplemented,
@@ -30,7 +30,9 @@ pub fn codegen_fulfill_obligation<'tcx>(
3030

3131
// Do the initial selection for the obligation. This yields the
3232
// shallow result we are looking for -- that is, what specific impl.
33-
tcx.infer_ctxt().enter(|infcx| {
33+
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bubble).enter(|infcx| {
34+
//~^ HACK `Bubble` is required for
35+
// this test to pass: type-alias-impl-trait/assoc-projection-ice.rs
3436
let mut selcx = SelectionContext::new(&infcx);
3537

3638
let obligation_cause = ObligationCause::dummy();
@@ -69,7 +71,8 @@ pub fn codegen_fulfill_obligation<'tcx>(
6971

7072
// Opaque types may have gotten their hidden types constrained, but we can ignore them safely
7173
// as they will get constrained elsewhere, too.
72-
let _opaque_types = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
74+
// (ouz-a) This is required for `type-alias-impl-trait/assoc-projection-ice.rs` to pass
75+
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
7376

7477
debug!("Cache miss: {trait_ref:?} => {impl_source:?}");
7578
Ok(&*tcx.arena.alloc(impl_source))

‎compiler/rustc_typeck/src/check/check.rs

Lines changed: 42 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc_hir::lang_items::LangItem;
1414
use rustc_hir::{ItemKind, Node, PathSegment};
1515
use rustc_infer::infer::outlives::env::OutlivesEnvironment;
1616
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
17-
use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
17+
use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt};
1818
use rustc_infer::traits::Obligation;
1919
use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
2020
use rustc_middle::hir::nested_filter;
@@ -731,52 +731,52 @@ fn check_opaque_meets_bounds<'tcx>(
731731
};
732732
let param_env = tcx.param_env(defining_use_anchor);
733733

734-
tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).enter(move |infcx| {
735-
let ocx = ObligationCtxt::new(&infcx);
736-
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
734+
tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::Bind(defining_use_anchor)).enter(
735+
move |infcx| {
736+
let ocx = ObligationCtxt::new(&infcx);
737+
let opaque_ty = tcx.mk_opaque(def_id.to_def_id(), substs);
737738

738-
let misc_cause = traits::ObligationCause::misc(span, hir_id);
739+
let misc_cause = traits::ObligationCause::misc(span, hir_id);
739740

740-
match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) {
741-
Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok),
742-
Err(ty_err) => {
743-
tcx.sess.delay_span_bug(
744-
span,
745-
&format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"),
746-
);
741+
match infcx.at(&misc_cause, param_env).eq(opaque_ty, hidden_type) {
742+
Ok(infer_ok) => ocx.register_infer_ok_obligations(infer_ok),
743+
Err(ty_err) => {
744+
tcx.sess.delay_span_bug(
745+
span,
746+
&format!("could not unify `{hidden_type}` with revealed type:\n{ty_err}"),
747+
);
748+
}
747749
}
748-
}
749750

750-
// Additionally require the hidden type to be well-formed with only the generics of the opaque type.
751-
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
752-
// hidden type is well formed even without those bounds.
753-
let predicate =
754-
ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into())).to_predicate(tcx);
755-
ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
756-
757-
// Check that all obligations are satisfied by the implementation's
758-
// version.
759-
let errors = ocx.select_all_or_error();
760-
if !errors.is_empty() {
761-
infcx.report_fulfillment_errors(&errors, None, false);
762-
}
763-
764-
match origin {
765-
// Checked when type checking the function containing them.
766-
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
767-
// Can have different predicates to their defining use
768-
hir::OpaqueTyOrigin::TyAlias => {
769-
let outlives_environment = OutlivesEnvironment::new(param_env);
770-
infcx.check_region_obligations_and_report_errors(
771-
defining_use_anchor,
772-
&outlives_environment,
773-
);
751+
// Additionally require the hidden type to be well-formed with only the generics of the opaque type.
752+
// Defining use functions may have more bounds than the opaque type, which is ok, as long as the
753+
// hidden type is well formed even without those bounds.
754+
let predicate = ty::Binder::dummy(ty::PredicateKind::WellFormed(hidden_type.into()))
755+
.to_predicate(tcx);
756+
ocx.register_obligation(Obligation::new(misc_cause, param_env, predicate));
757+
758+
// Check that all obligations are satisfied by the implementation's
759+
// version.
760+
let errors = ocx.select_all_or_error();
761+
if !errors.is_empty() {
762+
infcx.report_fulfillment_errors(&errors, None, false);
774763
}
775-
}
776-
777-
// Clean up after ourselves
778-
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
779-
});
764+
match origin {
765+
// Checked when type checking the function containing them.
766+
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
767+
// Can have different predicates to their defining use
768+
hir::OpaqueTyOrigin::TyAlias => {
769+
let outlives_environment = OutlivesEnvironment::new(param_env);
770+
infcx.check_region_obligations_and_report_errors(
771+
defining_use_anchor,
772+
&outlives_environment,
773+
);
774+
}
775+
}
776+
// Clean up after ourselves
777+
let _ = infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types();
778+
},
779+
);
780780
}
781781

782782
fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, id: hir::ItemId) {

‎compiler/rustc_typeck/src/check/compare_method.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,7 @@ pub fn check_type_bounds<'tcx>(
14601460
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
14611461
.map(|(bound, span)| {
14621462
debug!(?bound);
1463+
// this is where opaque type is found
14631464
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
14641465
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
14651466

@@ -1481,7 +1482,6 @@ pub fn check_type_bounds<'tcx>(
14811482
ocx.register_obligations(obligations);
14821483
ocx.register_obligation(obligation);
14831484
}
1484-
14851485
// Check that all obligations are satisfied by the implementation's
14861486
// version.
14871487
let errors = ocx.select_all_or_error();

‎src/test/ui/impl-trait/issues/issue-99348-impl-compatibility.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ type Tait = impl Sized;
66

77
impl Foo for Concrete {
88
type Item = Concrete;
9-
//~^ mismatched types
9+
//~^ type mismatch resolving
1010
}
1111

1212
impl Bar for Concrete {
Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
1-
error[E0308]: mismatched types
1+
error[E0271]: type mismatch resolving `<Concrete as Bar>::Other == Concrete`
22
--> $DIR/issue-99348-impl-compatibility.rs:8:17
33
|
44
LL | type Tait = impl Sized;
5-
| ---------- the expected opaque type
5+
| ---------- the found opaque type
66
...
77
LL | type Item = Concrete;
8-
| ^^^^^^^^ types differ
8+
| ^^^^^^^^ type mismatch resolving `<Concrete as Bar>::Other == Concrete`
99
|
10-
= note: expected opaque type `Tait`
11-
found struct `Concrete`
10+
note: expected this to be `Concrete`
11+
--> $DIR/issue-99348-impl-compatibility.rs:13:18
12+
|
13+
LL | type Other = Tait;
14+
| ^^^^
15+
= note: expected struct `Concrete`
16+
found opaque type `Tait`
17+
note: required by a bound in `Foo::Item`
18+
--> $DIR/issue-99348-impl-compatibility.rs:17:20
19+
|
20+
LL | type Item: Bar<Other = Self>;
21+
| ^^^^^^^^^^^^ required by this bound in `Foo::Item`
1222

1323
error: aborting due to previous error
1424

15-
For more information about this error, try `rustc --explain E0308`.
25+
For more information about this error, try `rustc --explain E0271`.

‎src/test/ui/parser/fn-header-semantic-fail.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ fn main() {
2727
struct Y;
2828
impl X for Y {
2929
async fn ft1() {} //~ ERROR functions in traits cannot be declared `async`
30-
//~^ ERROR impl has stricter requirements than trait
30+
//~^ ERROR has an incompatible type for trait
3131
unsafe fn ft2() {} // OK.
3232
const fn ft3() {} //~ ERROR functions in traits cannot be declared const
3333
extern "C" fn ft4() {}
@@ -36,7 +36,7 @@ fn main() {
3636
//~| ERROR functions in traits cannot be declared const
3737
//~| ERROR functions cannot be both `const` and `async`
3838
//~| ERROR cycle detected
39-
//~| ERROR impl has stricter requirements than trait
39+
//~| ERROR has an incompatible type for trait
4040
}
4141

4242
impl Y {

‎src/test/ui/parser/fn-header-semantic-fail.stderr

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -216,23 +216,41 @@ LL | | }
216216
LL | | }
217217
| |_^
218218

219-
error[E0276]: impl has stricter requirements than trait
220-
--> $DIR/fn-header-semantic-fail.rs:29:9
219+
error[E0053]: method `ft1` has an incompatible type for trait
220+
--> $DIR/fn-header-semantic-fail.rs:29:24
221221
|
222-
LL | async fn ft1();
223-
| --------------- definition of `ft1` from trait
224-
...
225222
LL | async fn ft1() {}
226-
| ^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
223+
| ^
224+
| |
225+
| checked the `Output` of this `async fn`, found opaque type
226+
| expected `()`, found opaque type
227+
|
228+
= note: while checking the return type of the `async fn`
229+
note: type in trait
230+
--> $DIR/fn-header-semantic-fail.rs:17:23
231+
|
232+
LL | async fn ft1();
233+
| ^
234+
= note: expected fn pointer `fn()`
235+
found fn pointer `fn() -> impl Future<Output = ()>`
227236

228-
error[E0276]: impl has stricter requirements than trait
229-
--> $DIR/fn-header-semantic-fail.rs:34:9
237+
error[E0053]: method `ft5` has an incompatible type for trait
238+
--> $DIR/fn-header-semantic-fail.rs:34:48
230239
|
231-
LL | const async unsafe extern "C" fn ft5();
232-
| --------------------------------------- definition of `ft5` from trait
233-
...
234240
LL | const async unsafe extern "C" fn ft5() {}
235-
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
241+
| ^
242+
| |
243+
| checked the `Output` of this `async fn`, found opaque type
244+
| expected `()`, found opaque type
245+
|
246+
= note: while checking the return type of the `async fn`
247+
note: type in trait
248+
--> $DIR/fn-header-semantic-fail.rs:21:47
249+
|
250+
LL | const async unsafe extern "C" fn ft5();
251+
| ^
252+
= note: expected fn pointer `unsafe extern "C" fn()`
253+
found fn pointer `unsafe extern "C" fn() -> impl Future<Output = ()>`
236254

237255
error[E0391]: cycle detected when computing type of `main::<impl at $DIR/fn-header-semantic-fail.rs:28:5: 28:17>::ft5::{opaque#0}`
238256
--> $DIR/fn-header-semantic-fail.rs:34:48
@@ -308,5 +326,5 @@ LL | | }
308326

309327
error: aborting due to 23 previous errors
310328

311-
Some errors have detailed explanations: E0276, E0379, E0391, E0706.
312-
For more information about an error, try `rustc --explain E0276`.
329+
Some errors have detailed explanations: E0053, E0379, E0391, E0706.
330+
For more information about an error, try `rustc --explain E0053`.

‎src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ trait B {
1414
impl B for A {
1515
async fn associated(); //~ ERROR without body
1616
//~^ ERROR cannot be declared `async`
17-
//~| ERROR impl has stricter requirements than trait
17+
//~| ERROR has an incompatible type for trait
1818
}
1919

2020
fn main() {}

‎src/test/ui/resolve/issue-70736-async-fn-no-body-def-collector.stderr

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,16 +44,25 @@ LL | async fn associated();
4444
= note: `async` trait functions are not currently supported
4545
= note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
4646

47-
error[E0276]: impl has stricter requirements than trait
48-
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:5
47+
error[E0053]: method `associated` has an incompatible type for trait
48+
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:15:26
4949
|
5050
LL | async fn associated();
51-
| ---------------------- definition of `associated` from trait
52-
...
51+
| ^
52+
| |
53+
| checked the `Output` of this `async fn`, found opaque type
54+
| expected `()`, found opaque type
55+
|
56+
= note: while checking the return type of the `async fn`
57+
note: type in trait
58+
--> $DIR/issue-70736-async-fn-no-body-def-collector.rs:11:26
59+
|
5360
LL | async fn associated();
54-
| ^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `(): Future`
61+
| ^
62+
= note: expected fn pointer `fn()`
63+
found fn pointer `fn() -> impl Future<Output = ()>`
5564

5665
error: aborting due to 6 previous errors
5766

58-
Some errors have detailed explanations: E0276, E0706.
59-
For more information about an error, try `rustc --explain E0276`.
67+
Some errors have detailed explanations: E0053, E0706.
68+
For more information about an error, try `rustc --explain E0053`.

‎src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
type Foo = impl Fn() -> Foo;
44

55
fn foo() -> Foo {
6-
//~^ ERROR: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
6+
//~^ ERROR: overflow evaluating the requirement
77
foo
88
}
99

‎src/test/ui/type-alias-impl-trait/issue-53398-cyclic-types.stderr

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
error[E0275]: overflow evaluating the requirement `fn() -> Foo {foo}: Sized`
1+
error[E0275]: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == fn() -> Foo {foo}`
22
--> $DIR/issue-53398-cyclic-types.rs:5:13
33
|
44
LL | fn foo() -> Foo {
55
| ^^^
6-
|
7-
= help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_53398_cyclic_types`)
86

97
error: aborting due to previous error
108

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(type_alias_impl_trait)]
2+
3+
type X = impl Sized;
4+
5+
trait Foo {
6+
type Bar: Iterator<Item = X>;
7+
}
8+
9+
impl Foo for () {
10+
type Bar = std::vec::IntoIter<u32>;
11+
//~^ ERROR type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X
12+
}
13+
14+
fn incoherent() {
15+
let f: X = 22_i32;
16+
}
17+
18+
fn main() {}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
error[E0271]: type mismatch resolving `<std::vec::IntoIter<u32> as Iterator>::Item == X`
2+
--> $DIR/issue-57961.rs:10:16
3+
|
4+
LL | type X = impl Sized;
5+
| ---------- the expected opaque type
6+
...
7+
LL | type Bar = std::vec::IntoIter<u32>;
8+
| ^^^^^^^^^^^^^^^^^^^^^^^ expected opaque type, found `u32`
9+
|
10+
= note: expected opaque type `X`
11+
found type `u32`
12+
note: required by a bound in `Foo::Bar`
13+
--> $DIR/issue-57961.rs:6:24
14+
|
15+
LL | type Bar: Iterator<Item = X>;
16+
| ^^^^^^^^ required by this bound in `Foo::Bar`
17+
18+
error: aborting due to previous error
19+
20+
For more information about this error, try `rustc --explain E0271`.

0 commit comments

Comments
 (0)
Please sign in to comment.