mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Auto merge of #122077 - oli-obk:eager_opaque_checks4, r=lcnr
Pass list of defineable opaque types into canonical queries This eliminates `DefiningAnchor::Bubble` for good and brings the old solver closer to the new one wrt cycles and nested obligations. At that point the difference between `DefiningAnchor::Bind([])` and `DefiningAnchor::Error` was academic. We only used the difference for some sanity checks, which actually had to be worked around in places, so I just removed `DefiningAnchor` entirely and just stored the list of opaques that may be defined. fixes #108498 fixes https://github.com/rust-lang/rust/issues/116877 * [x] run crater - https://github.com/rust-lang/rust/pull/122077#issuecomment-2013293931
This commit is contained in:
commit
b234e44944
@ -4,7 +4,6 @@ use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_index::{IndexSlice, IndexVec};
|
||||
use rustc_infer::infer::TyCtxtInferExt;
|
||||
use rustc_middle::mir::{Body, Promoted};
|
||||
use rustc_middle::traits::DefiningAnchor;
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use std::rc::Rc;
|
||||
|
||||
@ -106,7 +105,7 @@ pub fn get_body_with_borrowck_facts(
|
||||
options: ConsumerOptions,
|
||||
) -> BodyWithBorrowckFacts<'_> {
|
||||
let (input_body, promoted) = tcx.mir_promoted(def);
|
||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::bind(tcx, def)).build();
|
||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(def).build();
|
||||
let input_body: &Body<'_> = &input_body.borrow();
|
||||
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
||||
*super::do_mir_borrowck(&infcx, input_body, promoted, Some(options)).1.unwrap()
|
||||
|
@ -32,7 +32,6 @@ use rustc_infer::infer::{
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
use rustc_middle::mir::*;
|
||||
use rustc_middle::query::Providers;
|
||||
use rustc_middle::traits::DefiningAnchor;
|
||||
use rustc_middle::ty::{self, ParamEnv, RegionVid, TyCtxt};
|
||||
use rustc_session::lint::builtin::UNUSED_MUT;
|
||||
use rustc_span::{Span, Symbol};
|
||||
@ -126,7 +125,7 @@ fn mir_borrowck(tcx: TyCtxt<'_>, def: LocalDefId) -> &BorrowCheckResult<'_> {
|
||||
return tcx.arena.alloc(result);
|
||||
}
|
||||
|
||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(DefiningAnchor::bind(tcx, def)).build();
|
||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(def).build();
|
||||
let promoted: &IndexSlice<_, _> = &promoted.borrow();
|
||||
let opt_closure_req = do_mir_borrowck(&infcx, input_body, promoted, None).0;
|
||||
debug!("mir_borrowck done");
|
||||
|
@ -7,7 +7,6 @@ use rustc_infer::infer::TyCtxtInferExt as _;
|
||||
use rustc_infer::infer::{InferCtxt, NllRegionVariableOrigin};
|
||||
use rustc_infer::traits::{Obligation, ObligationCause};
|
||||
use rustc_macros::extension;
|
||||
use rustc_middle::traits::DefiningAnchor;
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable};
|
||||
use rustc_middle::ty::{GenericArgKind, GenericArgs};
|
||||
@ -133,6 +132,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
|
||||
|
||||
let ty =
|
||||
infcx.infer_opaque_definition_from_instantiation(opaque_type_key, concrete_type);
|
||||
|
||||
// Sometimes, when the hidden type is an inference variable, it can happen that
|
||||
// the hidden type becomes the opaque type itself. In this case, this was an opaque
|
||||
// usage of the opaque type and we can ignore it. This check is mirrored in typeck's
|
||||
// writeback.
|
||||
// FIXME(-Znext-solver): This should be unnecessary with the new solver.
|
||||
if let ty::Alias(ty::Opaque, alias_ty) = ty.kind()
|
||||
&& alias_ty.def_id == opaque_type_key.def_id.to_def_id()
|
||||
&& alias_ty.args == opaque_type_key.args
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// Sometimes two opaque types are the same only after we remap the generic parameters
|
||||
// back to the opaque type definition. E.g. we may have `OpaqueType<X, Y>` mapped to `(X, Y)`
|
||||
// and `OpaqueType<Y, X>` mapped to `(Y, X)`, and those are the same, but we only know that
|
||||
@ -321,13 +332,13 @@ fn check_opaque_type_well_formed<'tcx>(
|
||||
parent_def_id = tcx.local_parent(parent_def_id);
|
||||
}
|
||||
|
||||
// FIXME(-Znext-solver): We probably should use `DefiningAnchor::Bind(&[])`
|
||||
// FIXME(-Znext-solver): We probably should use `&[]` instead of
|
||||
// and prepopulate this `InferCtxt` with known opaque values, rather than
|
||||
// using the `Bind` anchor here. For now it's fine.
|
||||
// allowing opaque types to be defined and checking them after the fact.
|
||||
let infcx = tcx
|
||||
.infer_ctxt()
|
||||
.with_next_trait_solver(next_trait_solver)
|
||||
.with_opaque_type_inference(DefiningAnchor::bind(tcx, parent_def_id))
|
||||
.with_opaque_type_inference(parent_def_id)
|
||||
.build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let identity_args = GenericArgs::identity_for_item(tcx, def_id);
|
||||
|
@ -39,6 +39,12 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
|
||||
let TypeOpOutput { output, constraints, error_info } =
|
||||
op.fully_perform(self.infcx, locations.span(self.body))?;
|
||||
if cfg!(debug_assertions) {
|
||||
let data = self.infcx.take_and_reset_region_constraints();
|
||||
if !data.is_empty() {
|
||||
panic!("leftover region constraints: {data:#?}");
|
||||
}
|
||||
}
|
||||
|
||||
debug!(?output, ?constraints);
|
||||
|
||||
|
@ -13,7 +13,7 @@ use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
|
||||
use rustc_infer::traits::{Obligation, TraitEngineExt as _};
|
||||
use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
|
||||
use rustc_middle::middle::stability::EvalResult;
|
||||
use rustc_middle::traits::{DefiningAnchor, ObligationCauseCode};
|
||||
use rustc_middle::traits::ObligationCauseCode;
|
||||
use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
|
||||
use rustc_middle::ty::util::{Discr, InspectCoroutineFields, IntTypeExt};
|
||||
@ -345,10 +345,7 @@ fn check_opaque_meets_bounds<'tcx>(
|
||||
};
|
||||
let param_env = tcx.param_env(defining_use_anchor);
|
||||
|
||||
let infcx = tcx
|
||||
.infer_ctxt()
|
||||
.with_opaque_type_inference(DefiningAnchor::bind(tcx, defining_use_anchor))
|
||||
.build();
|
||||
let infcx = tcx.infer_ctxt().with_opaque_type_inference(defining_use_anchor).build();
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
|
||||
let args = match *origin {
|
||||
@ -1567,7 +1564,7 @@ pub(super) fn check_coroutine_obligations(
|
||||
.ignoring_regions()
|
||||
// Bind opaque types to type checking root, as they should have been checked by borrowck,
|
||||
// but may show up in some cases, like when (root) obligations are stalled in the new solver.
|
||||
.with_opaque_type_inference(DefiningAnchor::bind(tcx, typeck.hir_owner.def_id))
|
||||
.with_opaque_type_inference(typeck.hir_owner.def_id)
|
||||
.build();
|
||||
|
||||
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
|
||||
|
@ -730,8 +730,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
for ty in ret_ty.walk() {
|
||||
if let ty::GenericArgKind::Type(ty) = ty.unpack()
|
||||
&& let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *ty.kind()
|
||||
&& let Some(def_id) = def_id.as_local()
|
||||
&& self.opaque_type_origin(def_id).is_some()
|
||||
&& self.can_define_opaque_ty(def_id)
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::HirIdMap;
|
||||
use rustc_infer::infer::{InferCtxt, InferOk, TyCtxtInferExt};
|
||||
use rustc_middle::traits::DefiningAnchor;
|
||||
use rustc_middle::ty::visit::TypeVisitableExt;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_span::def_id::LocalDefIdMap;
|
||||
@ -78,11 +77,7 @@ impl<'tcx> TypeckRootCtxt<'tcx> {
|
||||
pub fn new(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Self {
|
||||
let hir_owner = tcx.local_def_id_to_hir_id(def_id).owner;
|
||||
|
||||
let infcx = tcx
|
||||
.infer_ctxt()
|
||||
.ignoring_regions()
|
||||
.with_opaque_type_inference(DefiningAnchor::bind(tcx, def_id))
|
||||
.build();
|
||||
let infcx = tcx.infer_ctxt().ignoring_regions().with_opaque_type_inference(def_id).build();
|
||||
let typeck_results = RefCell::new(ty::TypeckResults::new(hir_owner));
|
||||
|
||||
TypeckRootCtxt {
|
||||
|
@ -75,7 +75,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
pub fn fork_with_intercrate(&self, intercrate: bool) -> Self {
|
||||
Self {
|
||||
tcx: self.tcx,
|
||||
defining_use_anchor: self.defining_use_anchor,
|
||||
defining_opaque_types: self.defining_opaque_types,
|
||||
considering_regions: self.considering_regions,
|
||||
skip_leak_check: self.skip_leak_check,
|
||||
inner: self.inner.clone(),
|
||||
|
@ -42,7 +42,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
V: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let (param_env, value) = value.into_parts();
|
||||
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
|
||||
let mut param_env = self.tcx.canonical_param_env_cache.get_or_insert(
|
||||
self.tcx,
|
||||
param_env,
|
||||
query_state,
|
||||
@ -59,6 +59,8 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
},
|
||||
);
|
||||
|
||||
param_env.defining_opaque_types = self.defining_opaque_types;
|
||||
|
||||
Canonicalizer::canonicalize_with_base(
|
||||
param_env,
|
||||
value,
|
||||
@ -541,6 +543,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
max_universe: ty::UniverseIndex::ROOT,
|
||||
variables: List::empty(),
|
||||
value: (),
|
||||
defining_opaque_types: infcx.map(|i| i.defining_opaque_types).unwrap_or_default(),
|
||||
};
|
||||
Canonicalizer::canonicalize_with_base(
|
||||
base,
|
||||
@ -610,7 +613,15 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
.max()
|
||||
.unwrap_or(ty::UniverseIndex::ROOT);
|
||||
|
||||
Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) }
|
||||
assert!(
|
||||
!infcx.is_some_and(|infcx| infcx.defining_opaque_types != base.defining_opaque_types)
|
||||
);
|
||||
Canonical {
|
||||
max_universe,
|
||||
variables: canonical_variables,
|
||||
value: (base.value, out_value),
|
||||
defining_opaque_types: base.defining_opaque_types,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a canonical variable replacing `kind` from the input,
|
||||
|
@ -505,12 +505,9 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
let b = instantiate_value(self.tcx, &result_args, b);
|
||||
debug!(?a, ?b, "constrain opaque type");
|
||||
// We use equate here instead of, for example, just registering the
|
||||
// opaque type's hidden value directly, because we may be instantiating
|
||||
// a query response that was canonicalized in an InferCtxt that had
|
||||
// a different defining anchor. In that case, we may have inferred
|
||||
// `NonLocalOpaque := LocalOpaque` but can only instantiate it in
|
||||
// the other direction as `LocalOpaque := NonLocalOpaque`. Using eq
|
||||
// here allows us to try both directions (in `InferCtxt::handle_opaque_type`).
|
||||
// opaque type's hidden value directly, because the hidden type may have been an inference
|
||||
// variable that got constrained to the opaque type itself. In that case we want to equate
|
||||
// the generic args of the opaque with the generic params of its hidden type version.
|
||||
obligations.extend(
|
||||
self.at(cause, param_env)
|
||||
.eq(
|
||||
|
@ -34,7 +34,7 @@ use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKin
|
||||
use rustc_middle::infer::unify_key::{ConstVidKey, EffectVidKey};
|
||||
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
|
||||
use rustc_middle::mir::ConstraintCategory;
|
||||
use rustc_middle::traits::{select, DefiningAnchor};
|
||||
use rustc_middle::traits::select;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::fold::BoundVarReplacerDelegate;
|
||||
use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
|
||||
@ -243,18 +243,8 @@ impl<'tcx> InferCtxtInner<'tcx> {
|
||||
pub struct InferCtxt<'tcx> {
|
||||
pub tcx: TyCtxt<'tcx>,
|
||||
|
||||
/// The `DefId` of the item in whose context we are performing inference or typeck.
|
||||
/// It is used to check whether an opaque type use is a defining use.
|
||||
///
|
||||
/// If it is `DefiningAnchor::Bubble`, we can't resolve opaque types here and need to bubble up
|
||||
/// the obligation. This frequently happens for
|
||||
/// short lived InferCtxt within queries. The opaque type obligations are forwarded
|
||||
/// to the outside until the end up in an `InferCtxt` for typeck or borrowck.
|
||||
///
|
||||
/// Its default value is `DefiningAnchor::Bind(&[])`, which means no opaque types may be defined.
|
||||
/// This way it is easier to catch errors that
|
||||
/// might come up during inference or typeck.
|
||||
pub defining_use_anchor: DefiningAnchor<'tcx>,
|
||||
/// The `DefIds` of the opaque types that may have their hidden types constrained.
|
||||
defining_opaque_types: &'tcx ty::List<LocalDefId>,
|
||||
|
||||
/// Whether this inference context should care about region obligations in
|
||||
/// the root universe. Most notably, this is used during hir typeck as region
|
||||
@ -401,6 +391,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
|
||||
fn probe_ct_var(&self, vid: ConstVid) -> Option<ty::Const<'tcx>> {
|
||||
self.probe_const_var(vid).ok()
|
||||
}
|
||||
|
||||
fn defining_opaque_types(&self) -> &'tcx ty::List<LocalDefId> {
|
||||
self.defining_opaque_types
|
||||
}
|
||||
}
|
||||
|
||||
/// See the `error_reporting` module for more details.
|
||||
@ -615,7 +609,7 @@ impl fmt::Display for FixupError {
|
||||
/// Used to configure inference contexts before their creation.
|
||||
pub struct InferCtxtBuilder<'tcx> {
|
||||
tcx: TyCtxt<'tcx>,
|
||||
defining_use_anchor: DefiningAnchor<'tcx>,
|
||||
defining_opaque_types: &'tcx ty::List<LocalDefId>,
|
||||
considering_regions: bool,
|
||||
skip_leak_check: bool,
|
||||
/// Whether we are in coherence mode.
|
||||
@ -630,7 +624,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
fn infer_ctxt(self) -> InferCtxtBuilder<'tcx> {
|
||||
InferCtxtBuilder {
|
||||
tcx: self,
|
||||
defining_use_anchor: DefiningAnchor::Bind(ty::List::empty()),
|
||||
defining_opaque_types: ty::List::empty(),
|
||||
considering_regions: true,
|
||||
skip_leak_check: false,
|
||||
intercrate: false,
|
||||
@ -646,8 +640,16 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||
/// It is only meant to be called in two places, for typeck
|
||||
/// (via `Inherited::build`) and for the inference context used
|
||||
/// in mir borrowck.
|
||||
pub fn with_opaque_type_inference(mut self, defining_use_anchor: DefiningAnchor<'tcx>) -> Self {
|
||||
self.defining_use_anchor = defining_use_anchor;
|
||||
pub fn with_opaque_type_inference(mut self, defining_anchor: LocalDefId) -> Self {
|
||||
self.defining_opaque_types = self.tcx.opaque_types_defined_by(defining_anchor);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_defining_opaque_types(
|
||||
mut self,
|
||||
defining_opaque_types: &'tcx ty::List<LocalDefId>,
|
||||
) -> Self {
|
||||
self.defining_opaque_types = defining_opaque_types;
|
||||
self
|
||||
}
|
||||
|
||||
@ -679,14 +681,14 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||
/// the bound values in `C` to their instantiated values in `V`
|
||||
/// (in other words, `S(C) = V`).
|
||||
pub fn build_with_canonical<T>(
|
||||
&mut self,
|
||||
self,
|
||||
span: Span,
|
||||
canonical: &Canonical<'tcx, T>,
|
||||
) -> (InferCtxt<'tcx>, T, CanonicalVarValues<'tcx>)
|
||||
where
|
||||
T: TypeFoldable<TyCtxt<'tcx>>,
|
||||
{
|
||||
let infcx = self.build();
|
||||
let infcx = self.with_defining_opaque_types(canonical.defining_opaque_types).build();
|
||||
let (value, args) = infcx.instantiate_canonical(span, canonical);
|
||||
(infcx, value, args)
|
||||
}
|
||||
@ -694,7 +696,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||
pub fn build(&mut self) -> InferCtxt<'tcx> {
|
||||
let InferCtxtBuilder {
|
||||
tcx,
|
||||
defining_use_anchor,
|
||||
defining_opaque_types,
|
||||
considering_regions,
|
||||
skip_leak_check,
|
||||
intercrate,
|
||||
@ -702,7 +704,7 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||
} = *self;
|
||||
InferCtxt {
|
||||
tcx,
|
||||
defining_use_anchor,
|
||||
defining_opaque_types,
|
||||
considering_regions,
|
||||
skip_leak_check,
|
||||
inner: RefCell::new(InferCtxtInner::new()),
|
||||
@ -1230,6 +1232,12 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
self.inner.borrow().opaque_type_storage.opaque_types.clone()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn can_define_opaque_ty(&self, id: impl Into<DefId>) -> bool {
|
||||
let Some(id) = id.into().as_local() else { return false };
|
||||
self.defining_opaque_types.contains(&id)
|
||||
}
|
||||
|
||||
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
|
||||
self.resolve_vars_if_possible(t).to_string()
|
||||
}
|
||||
|
@ -4,11 +4,10 @@ use crate::errors::OpaqueHiddenTypeDiag;
|
||||
use crate::infer::{InferCtxt, InferOk};
|
||||
use crate::traits::{self, PredicateObligation};
|
||||
use hir::def_id::{DefId, LocalDefId};
|
||||
use hir::OpaqueTyOrigin;
|
||||
use rustc_data_structures::fx::FxIndexMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_hir as hir;
|
||||
use rustc_middle::traits::{DefiningAnchor, ObligationCause};
|
||||
use rustc_middle::traits::ObligationCause;
|
||||
use rustc_middle::ty::error::{ExpectedFound, TypeError};
|
||||
use rustc_middle::ty::fold::BottomUpFolder;
|
||||
use rustc_middle::ty::GenericArgKind;
|
||||
@ -54,16 +53,13 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
}
|
||||
|
||||
let mut obligations = vec![];
|
||||
let replace_opaque_type = |def_id: DefId| {
|
||||
def_id.as_local().is_some_and(|def_id| self.opaque_type_origin(def_id).is_some())
|
||||
};
|
||||
let value = value.fold_with(&mut BottomUpFolder {
|
||||
tcx: self.tcx,
|
||||
lt_op: |lt| lt,
|
||||
ct_op: |ct| ct,
|
||||
ty_op: |ty| match *ty.kind() {
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. })
|
||||
if replace_opaque_type(def_id) && !ty.has_escaping_bound_vars() =>
|
||||
if self.can_define_opaque_ty(def_id) && !ty.has_escaping_bound_vars() =>
|
||||
{
|
||||
let def_span = self.tcx.def_span(def_id);
|
||||
let span = if span.contains(def_span) { def_span } else { span };
|
||||
@ -106,56 +102,52 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
b,
|
||||
));
|
||||
}
|
||||
match self.defining_use_anchor {
|
||||
DefiningAnchor::Bind(_) => {
|
||||
// Check that this is `impl Trait` type is
|
||||
// declared by `parent_def_id` -- i.e., one whose
|
||||
// value we are inferring. At present, this is
|
||||
// always true during the first phase of
|
||||
// type-check, but not always true later on during
|
||||
// NLL. Once we support named opaque types more fully,
|
||||
// this same scenario will be able to arise during all phases.
|
||||
//
|
||||
// Here is an example using type alias `impl Trait`
|
||||
// that indicates the distinction we are checking for:
|
||||
//
|
||||
// ```rust
|
||||
// mod a {
|
||||
// pub type Foo = impl Iterator;
|
||||
// pub fn make_foo() -> Foo { .. }
|
||||
// }
|
||||
//
|
||||
// mod b {
|
||||
// fn foo() -> a::Foo { a::make_foo() }
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Here, the return type of `foo` references an
|
||||
// `Opaque` indeed, but not one whose value is
|
||||
// presently being inferred. You can get into a
|
||||
// similar situation with closure return types
|
||||
// today:
|
||||
//
|
||||
// ```rust
|
||||
// fn foo() -> impl Iterator { .. }
|
||||
// fn bar() {
|
||||
// let x = || foo(); // returns the Opaque assoc with `foo`
|
||||
// }
|
||||
// ```
|
||||
if self.opaque_type_origin(def_id).is_none() {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
DefiningAnchor::Bubble => {}
|
||||
// Check that this is `impl Trait` type is
|
||||
// declared by `parent_def_id` -- i.e., one whose
|
||||
// value we are inferring. At present, this is
|
||||
// always true during the first phase of
|
||||
// type-check, but not always true later on during
|
||||
// NLL. Once we support named opaque types more fully,
|
||||
// this same scenario will be able to arise during all phases.
|
||||
//
|
||||
// Here is an example using type alias `impl Trait`
|
||||
// that indicates the distinction we are checking for:
|
||||
//
|
||||
// ```rust
|
||||
// mod a {
|
||||
// pub type Foo = impl Iterator;
|
||||
// pub fn make_foo() -> Foo { .. }
|
||||
// }
|
||||
//
|
||||
// mod b {
|
||||
// fn foo() -> a::Foo { a::make_foo() }
|
||||
// }
|
||||
// ```
|
||||
//
|
||||
// Here, the return type of `foo` references an
|
||||
// `Opaque` indeed, but not one whose value is
|
||||
// presently being inferred. You can get into a
|
||||
// similar situation with closure return types
|
||||
// today:
|
||||
//
|
||||
// ```rust
|
||||
// fn foo() -> impl Iterator { .. }
|
||||
// fn bar() {
|
||||
// let x = || foo(); // returns the Opaque assoc with `foo`
|
||||
// }
|
||||
// ```
|
||||
if !self.can_define_opaque_ty(def_id) {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }) = *b.kind() {
|
||||
// We could accept this, but there are various ways to handle this situation, and we don't
|
||||
// want to make a decision on it right now. Likely this case is so super rare anyway, that
|
||||
// no one encounters it in practice.
|
||||
// It does occur however in `fn fut() -> impl Future<Output = i32> { async { 42 } }`,
|
||||
// where it is of no concern, so we only check for TAITs.
|
||||
if let Some(OpaqueTyOrigin::TyAlias { .. }) =
|
||||
b_def_id.as_local().and_then(|b_def_id| self.opaque_type_origin(b_def_id))
|
||||
if self.can_define_opaque_ty(b_def_id)
|
||||
&& self.tcx.is_type_alias_impl_trait(b_def_id)
|
||||
{
|
||||
self.tcx.dcx().emit_err(OpaqueHiddenTypeDiag {
|
||||
span: cause.span,
|
||||
@ -367,20 +359,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
op: |r| self.member_constraint(opaque_type_key, span, concrete_ty, r, &choice_regions),
|
||||
});
|
||||
}
|
||||
|
||||
/// Returns the origin of the opaque type `def_id` if we're currently
|
||||
/// in its defining scope.
|
||||
#[instrument(skip(self), level = "trace", ret)]
|
||||
pub fn opaque_type_origin(&self, def_id: LocalDefId) -> Option<OpaqueTyOrigin> {
|
||||
let defined_opaque_types = match self.defining_use_anchor {
|
||||
DefiningAnchor::Bubble => return None,
|
||||
DefiningAnchor::Bind(bind) => bind,
|
||||
};
|
||||
|
||||
let origin = self.tcx.opaque_type_origin(def_id);
|
||||
|
||||
defined_opaque_types.contains(&def_id).then_some(origin)
|
||||
}
|
||||
}
|
||||
|
||||
/// Visitor that requires that (almost) all regions in the type visited outlive
|
||||
|
@ -153,11 +153,6 @@ pub struct QueryResponse<'tcx, R> {
|
||||
pub var_values: CanonicalVarValues<'tcx>,
|
||||
pub region_constraints: QueryRegionConstraints<'tcx>,
|
||||
pub certainty: Certainty,
|
||||
/// List of opaque types which we tried to compare to another type.
|
||||
/// Inside the query we don't know yet whether the opaque type actually
|
||||
/// should get its hidden type inferred. So we bubble the opaque type
|
||||
/// and the type it was compared against upwards and let the query caller
|
||||
/// handle it.
|
||||
pub opaque_types: Vec<(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)>,
|
||||
pub value: R,
|
||||
}
|
||||
@ -330,6 +325,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
|
||||
max_universe: ty::UniverseIndex::ROOT,
|
||||
variables: List::empty(),
|
||||
value: key,
|
||||
defining_opaque_types: ty::List::empty(),
|
||||
};
|
||||
}
|
||||
|
||||
@ -340,6 +336,14 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
|
||||
match self.map.borrow().entry(key) {
|
||||
Entry::Occupied(e) => {
|
||||
let (canonical, var_values) = e.get();
|
||||
if cfg!(debug_assertions) {
|
||||
let mut state = state.clone();
|
||||
let rerun_canonical = canonicalize_op(tcx, key, &mut state);
|
||||
assert_eq!(rerun_canonical, *canonical);
|
||||
let OriginalQueryValues { var_values: rerun_var_values, universe_map } = state;
|
||||
assert_eq!(universe_map.len(), 1);
|
||||
assert_eq!(**var_values, *rerun_var_values);
|
||||
}
|
||||
state.var_values.extend_from_slice(var_values);
|
||||
*canonical
|
||||
}
|
||||
|
@ -338,10 +338,11 @@ macro_rules! define_callbacks {
|
||||
|
||||
pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
|
||||
|
||||
// Ensure that keys grow no larger than 64 bytes
|
||||
// Ensure that keys grow no larger than 72 bytes by accident.
|
||||
// Increase this limit if necessary, but do try to keep the size low if possible
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
|
||||
const _: () = {
|
||||
if mem::size_of::<Key<'static>>() > 64 {
|
||||
if mem::size_of::<Key<'static>>() > 72 {
|
||||
panic!("{}", concat!(
|
||||
"the query `",
|
||||
stringify!($name),
|
||||
@ -352,7 +353,8 @@ macro_rules! define_callbacks {
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure that values grow no larger than 64 bytes
|
||||
// Ensure that values grow no larger than 64 bytes by accident.
|
||||
// Increase this limit if necessary, but do try to keep the size low if possible
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
|
||||
const _: () = {
|
||||
if mem::size_of::<Value<'static>>() > 64 {
|
||||
|
@ -12,8 +12,8 @@ pub mod util;
|
||||
use crate::infer::canonical::Canonical;
|
||||
use crate::mir::ConstraintCategory;
|
||||
use crate::ty::abstract_const::NotConstEvaluatable;
|
||||
use crate::ty::GenericArgsRef;
|
||||
use crate::ty::{self, AdtKind, Ty};
|
||||
use crate::ty::{GenericArgsRef, TyCtxt};
|
||||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{Applicability, Diag, EmissionGuarantee};
|
||||
@ -997,33 +997,3 @@ pub enum CodegenObligationError {
|
||||
Unimplemented,
|
||||
FulfillmentError,
|
||||
}
|
||||
|
||||
/// Defines the treatment of opaque types in a given inference context.
|
||||
///
|
||||
/// This affects both what opaques are allowed to be defined, but also whether
|
||||
/// opaques are replaced with inference vars eagerly in the old solver (e.g.
|
||||
/// in projection, and in the signature during function type-checking).
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub enum DefiningAnchor<'tcx> {
|
||||
/// Define opaques which are in-scope of the current item being analyzed.
|
||||
/// Also, eagerly replace these opaque types in `replace_opaque_types_with_inference_vars`.
|
||||
///
|
||||
/// If the list is empty, do not allow any opaques to be defined. This is used to catch type mismatch
|
||||
/// errors when handling opaque types, and also should be used when we would
|
||||
/// otherwise reveal opaques (such as [`Reveal::All`] reveal mode).
|
||||
Bind(&'tcx ty::List<LocalDefId>),
|
||||
/// In contexts where we don't currently know what opaques are allowed to be
|
||||
/// defined, such as (old solver) canonical queries, we will simply allow
|
||||
/// opaques to be defined, but "bubble" them up in the canonical response or
|
||||
/// otherwise treat them to be handled later.
|
||||
///
|
||||
/// We do not eagerly replace opaque types in `replace_opaque_types_with_inference_vars`,
|
||||
/// which may affect what predicates pass and fail in the old trait solver.
|
||||
Bubble,
|
||||
}
|
||||
|
||||
impl<'tcx> DefiningAnchor<'tcx> {
|
||||
pub fn bind(tcx: TyCtxt<'tcx>, item: LocalDefId) -> Self {
|
||||
Self::Bind(tcx.opaque_types_defined_by(item))
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use rustc_span::def_id::DefId;
|
||||
|
||||
use crate::infer::canonical::{CanonicalVarValues, QueryRegionConstraints};
|
||||
use crate::traits::query::NoSolution;
|
||||
use crate::traits::{Canonical, DefiningAnchor};
|
||||
use crate::traits::Canonical;
|
||||
use crate::ty::{
|
||||
self, FallibleTypeFolder, ToPredicate, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeVisitable,
|
||||
TypeVisitor,
|
||||
@ -114,7 +114,6 @@ impl MaybeCause {
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, HashStable, TypeFoldable, TypeVisitable)]
|
||||
pub struct QueryInput<'tcx, T> {
|
||||
pub goal: Goal<'tcx, T>,
|
||||
pub anchor: DefiningAnchor<'tcx>,
|
||||
pub predefined_opaques_in_body: PredefinedOpaques<'tcx>,
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ impl UpvarId {
|
||||
|
||||
/// Information describing the capture of an upvar. This is computed
|
||||
/// during `typeck`, specifically by `regionck`.
|
||||
#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
|
||||
#[derive(Eq, PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable, Hash)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub enum UpvarCapture {
|
||||
/// Upvar is captured by value. This is always true when the
|
||||
@ -73,7 +73,7 @@ pub type RootVariableMinCaptureList<'tcx> = FxIndexMap<hir::HirId, MinCaptureLis
|
||||
pub type MinCaptureList<'tcx> = Vec<CapturedPlace<'tcx>>;
|
||||
|
||||
/// A composite describing a `Place` that is captured by a closure.
|
||||
#[derive(PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable)]
|
||||
#[derive(Eq, PartialEq, Clone, Debug, TyEncodable, TyDecodable, HashStable, Hash)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct CapturedPlace<'tcx> {
|
||||
/// Name and span where the binding happens.
|
||||
@ -192,7 +192,7 @@ impl<'tcx> CapturedPlace<'tcx> {
|
||||
#[derive(Copy, Clone, Debug, HashStable)]
|
||||
pub struct ClosureTypeInfo<'tcx> {
|
||||
user_provided_sig: ty::CanonicalPolyFnSig<'tcx>,
|
||||
captures: &'tcx [&'tcx ty::CapturedPlace<'tcx>],
|
||||
captures: &'tcx ty::List<&'tcx ty::CapturedPlace<'tcx>>,
|
||||
kind_origin: Option<&'tcx (Span, HirPlace<'tcx>)>,
|
||||
}
|
||||
|
||||
@ -201,7 +201,7 @@ fn closure_typeinfo<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> ClosureTypeInfo
|
||||
let typeck_results = tcx.typeck(def);
|
||||
let user_provided_sig = typeck_results.user_provided_sigs[&def];
|
||||
let captures = typeck_results.closure_min_captures_flattened(def);
|
||||
let captures = tcx.arena.alloc_from_iter(captures);
|
||||
let captures = tcx.mk_captures_from_iter(captures);
|
||||
let hir_id = tcx.local_def_id_to_hir_id(def);
|
||||
let kind_origin = typeck_results.closure_kind_origins().get(hir_id);
|
||||
ClosureTypeInfo { user_provided_sig, captures, kind_origin }
|
||||
@ -253,7 +253,7 @@ pub fn is_ancestor_or_same_capture(
|
||||
/// Part of `MinCaptureInformationMap`; describes the capture kind (&, &mut, move)
|
||||
/// for a particular capture as well as identifying the part of the source code
|
||||
/// that triggered this capture to occur.
|
||||
#[derive(PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable)]
|
||||
#[derive(Eq, PartialEq, Clone, Debug, Copy, TyEncodable, TyDecodable, HashStable, Hash)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub struct CaptureInfo {
|
||||
/// Expr Id pointing to use that resulted in selecting the current capture kind
|
||||
@ -332,7 +332,7 @@ pub fn place_to_string_for_capture<'tcx>(tcx: TyCtxt<'tcx>, place: &HirPlace<'tc
|
||||
curr_string
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, HashStable)]
|
||||
#[derive(Eq, Clone, PartialEq, Debug, TyEncodable, TyDecodable, Copy, HashStable, Hash)]
|
||||
#[derive(TypeFoldable, TypeVisitable)]
|
||||
pub enum BorrowKind {
|
||||
/// Data must be immutable and is aliasable.
|
||||
|
@ -455,6 +455,12 @@ impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D> for ty::List<Lo
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> Decodable<D> for &'tcx ty::List<LocalDefId> {
|
||||
fn decode(d: &mut D) -> Self {
|
||||
RefDecodable::decode(d)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, D: TyDecoder<I = TyCtxt<'tcx>>> RefDecodable<'tcx, D>
|
||||
for ty::List<(VariantIdx, FieldIdx)>
|
||||
{
|
||||
|
@ -85,6 +85,7 @@ use std::ops::{Bound, Deref};
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type DefId = DefId;
|
||||
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
|
||||
type AdtDef = ty::AdtDef<'tcx>;
|
||||
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
||||
type GenericArg = ty::GenericArg<'tcx>;
|
||||
@ -168,6 +169,7 @@ pub struct CtxtInterners<'tcx> {
|
||||
predefined_opaques_in_body: InternedSet<'tcx, PredefinedOpaquesData<'tcx>>,
|
||||
fields: InternedSet<'tcx, List<FieldIdx>>,
|
||||
local_def_ids: InternedSet<'tcx, List<LocalDefId>>,
|
||||
captures: InternedSet<'tcx, List<&'tcx ty::CapturedPlace<'tcx>>>,
|
||||
offset_of: InternedSet<'tcx, List<(VariantIdx, FieldIdx)>>,
|
||||
}
|
||||
|
||||
@ -196,6 +198,7 @@ impl<'tcx> CtxtInterners<'tcx> {
|
||||
predefined_opaques_in_body: Default::default(),
|
||||
fields: Default::default(),
|
||||
local_def_ids: Default::default(),
|
||||
captures: Default::default(),
|
||||
offset_of: Default::default(),
|
||||
}
|
||||
}
|
||||
@ -1912,6 +1915,7 @@ slice_interners!(
|
||||
bound_variable_kinds: pub mk_bound_variable_kinds(ty::BoundVariableKind),
|
||||
fields: pub mk_fields(FieldIdx),
|
||||
local_def_ids: intern_local_def_ids(LocalDefId),
|
||||
captures: intern_captures(&'tcx ty::CapturedPlace<'tcx>),
|
||||
offset_of: pub mk_offset_of((VariantIdx, FieldIdx)),
|
||||
);
|
||||
|
||||
@ -2233,6 +2237,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
T::collect_and_apply(iter, |xs| self.mk_local_def_ids(xs))
|
||||
}
|
||||
|
||||
pub fn mk_captures_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: CollectAndApply<
|
||||
&'tcx ty::CapturedPlace<'tcx>,
|
||||
&'tcx List<&'tcx ty::CapturedPlace<'tcx>>,
|
||||
>,
|
||||
{
|
||||
T::collect_and_apply(iter, |xs| self.intern_captures(xs))
|
||||
}
|
||||
|
||||
pub fn mk_const_list_from_iter<I, T>(self, iter: I) -> T::Output
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
|
@ -55,6 +55,12 @@ struct ListSkeleton<H, T> {
|
||||
data: [T; 0],
|
||||
}
|
||||
|
||||
impl<T> Default for &List<T> {
|
||||
fn default() -> Self {
|
||||
List::empty()
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
/// A dummy type used to force `List` to be unsized while not requiring
|
||||
/// references to it be wide pointers.
|
||||
|
@ -69,7 +69,8 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
|
||||
|
||||
let (max_universe, variables) = canonicalizer.finalize();
|
||||
|
||||
Canonical { max_universe, variables, value }
|
||||
let defining_opaque_types = infcx.defining_opaque_types();
|
||||
Canonical { defining_opaque_types, max_universe, variables, value }
|
||||
}
|
||||
|
||||
fn finalize(self) -> (ty::UniverseIndex, I::CanonicalVars) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
|
||||
use crate::traits::{self, DefiningAnchor, ObligationCtxt, SelectionContext};
|
||||
use crate::traits::{self, ObligationCtxt, SelectionContext};
|
||||
|
||||
use crate::traits::TraitEngineExt as _;
|
||||
use rustc_hir::def_id::DefId;
|
||||
@ -132,9 +132,8 @@ impl<'tcx> InferCtxtBuilder<'tcx> {
|
||||
R: Debug + TypeFoldable<TyCtxt<'tcx>>,
|
||||
Canonical<'tcx, QueryResponse<'tcx, R>>: ArenaAllocatable<'tcx>,
|
||||
{
|
||||
let (infcx, key, canonical_inference_vars) = self
|
||||
.with_opaque_type_inference(DefiningAnchor::Bubble)
|
||||
.build_with_canonical(DUMMY_SP, canonical_key);
|
||||
let (infcx, key, canonical_inference_vars) =
|
||||
self.build_with_canonical(DUMMY_SP, canonical_key);
|
||||
let ocx = ObligationCtxt::new(&infcx);
|
||||
let value = operation(&ocx, key)?;
|
||||
ocx.make_canonicalized_query_response(canonical_inference_vars, value)
|
||||
|
@ -68,7 +68,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
&mut orig_values,
|
||||
QueryInput {
|
||||
goal,
|
||||
anchor: self.infcx.defining_use_anchor,
|
||||
predefined_opaques_in_body: self
|
||||
.tcx()
|
||||
.mk_predefined_opaques_in_body(PredefinedOpaquesData { opaque_types }),
|
||||
|
@ -1,5 +1,5 @@
|
||||
use rustc_data_structures::stack::ensure_sufficient_stack;
|
||||
use rustc_hir::def_id::{DefId, LocalDefId};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_infer::infer::at::ToTrace;
|
||||
use rustc_infer::infer::canonical::CanonicalVarValues;
|
||||
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
||||
@ -230,7 +230,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||
.infer_ctxt()
|
||||
.intercrate(intercrate)
|
||||
.with_next_trait_solver(true)
|
||||
.with_opaque_type_inference(canonical_input.value.anchor)
|
||||
.build_with_canonical(DUMMY_SP, &canonical_input);
|
||||
|
||||
let mut ecx = EvalCtxt {
|
||||
@ -936,8 +935,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn can_define_opaque_ty(&self, def_id: LocalDefId) -> bool {
|
||||
self.infcx.opaque_type_origin(def_id).is_some()
|
||||
pub(super) fn can_define_opaque_ty(&self, def_id: impl Into<DefId>) -> bool {
|
||||
self.infcx.can_define_opaque_ty(def_id)
|
||||
}
|
||||
|
||||
pub(super) fn insert_hidden_type(
|
||||
|
@ -316,5 +316,6 @@ fn response_no_constraints_raw<'tcx>(
|
||||
external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
|
||||
certainty,
|
||||
},
|
||||
defining_opaque_types: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -155,10 +155,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
|
||||
if let ty::Alias(ty::Opaque, opaque_ty) = goal.predicate.self_ty().kind() {
|
||||
if matches!(goal.param_env.reveal(), Reveal::All)
|
||||
|| matches!(ecx.solver_mode(), SolverMode::Coherence)
|
||||
|| opaque_ty
|
||||
.def_id
|
||||
.as_local()
|
||||
.is_some_and(|def_id| ecx.can_define_opaque_ty(def_id))
|
||||
|| ecx.can_define_opaque_ty(opaque_ty.def_id)
|
||||
{
|
||||
return Err(NoSolution);
|
||||
}
|
||||
|
@ -159,53 +159,70 @@ where
|
||||
.0);
|
||||
}
|
||||
|
||||
let mut error_info = None;
|
||||
let mut region_constraints = QueryRegionConstraints::default();
|
||||
let (output, error_info, mut obligations, _) =
|
||||
Q::fully_perform_into(self, infcx, &mut region_constraints, span).map_err(|_| {
|
||||
infcx.dcx().span_delayed_bug(span, format!("error performing {self:?}"))
|
||||
})?;
|
||||
|
||||
// Typically, instantiating NLL query results does not
|
||||
// create obligations. However, in some cases there
|
||||
// are unresolved type variables, and unify them *can*
|
||||
// create obligations. In that case, we have to go
|
||||
// fulfill them. We do this via a (recursive) query.
|
||||
while !obligations.is_empty() {
|
||||
trace!("{:#?}", obligations);
|
||||
let mut progress = false;
|
||||
for obligation in std::mem::take(&mut obligations) {
|
||||
let obligation = infcx.resolve_vars_if_possible(obligation);
|
||||
match ProvePredicate::fully_perform_into(
|
||||
obligation.param_env.and(ProvePredicate::new(obligation.predicate)),
|
||||
infcx,
|
||||
&mut region_constraints,
|
||||
span,
|
||||
) {
|
||||
Ok(((), _, new, certainty)) => {
|
||||
obligations.extend(new);
|
||||
progress = true;
|
||||
if let Certainty::Ambiguous = certainty {
|
||||
obligations.push(obligation);
|
||||
// HACK(type_alias_impl_trait): When moving an opaque type to hidden type mapping from the query to the current inferctxt,
|
||||
// we sometimes end up with `Opaque<'a> = Opaque<'b>` instead of an actual hidden type. In that case we don't register a
|
||||
// hidden type but just equate the lifetimes. Thus we need to scrape the region constraints even though we're also manually
|
||||
// collecting region constraints via `region_constraints`.
|
||||
let (mut output, _) = scrape_region_constraints(
|
||||
infcx,
|
||||
|_ocx| {
|
||||
let (output, ei, mut obligations, _) =
|
||||
Q::fully_perform_into(self, infcx, &mut region_constraints, span)?;
|
||||
error_info = ei;
|
||||
|
||||
// Typically, instantiating NLL query results does not
|
||||
// create obligations. However, in some cases there
|
||||
// are unresolved type variables, and unify them *can*
|
||||
// create obligations. In that case, we have to go
|
||||
// fulfill them. We do this via a (recursive) query.
|
||||
while !obligations.is_empty() {
|
||||
trace!("{:#?}", obligations);
|
||||
let mut progress = false;
|
||||
for obligation in std::mem::take(&mut obligations) {
|
||||
let obligation = infcx.resolve_vars_if_possible(obligation);
|
||||
match ProvePredicate::fully_perform_into(
|
||||
obligation.param_env.and(ProvePredicate::new(obligation.predicate)),
|
||||
infcx,
|
||||
&mut region_constraints,
|
||||
span,
|
||||
) {
|
||||
Ok(((), _, new, certainty)) => {
|
||||
obligations.extend(new);
|
||||
progress = true;
|
||||
if let Certainty::Ambiguous = certainty {
|
||||
obligations.push(obligation);
|
||||
}
|
||||
}
|
||||
Err(_) => obligations.push(obligation),
|
||||
}
|
||||
}
|
||||
Err(_) => obligations.push(obligation),
|
||||
if !progress {
|
||||
infcx.dcx().span_bug(
|
||||
span,
|
||||
format!("ambiguity processing {obligations:?} from {self:?}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
if !progress {
|
||||
infcx
|
||||
.dcx()
|
||||
.span_bug(span, format!("ambiguity processing {obligations:?} from {self:?}"));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(TypeOpOutput {
|
||||
output,
|
||||
constraints: if region_constraints.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(infcx.tcx.arena.alloc(region_constraints))
|
||||
Ok(output)
|
||||
},
|
||||
error_info,
|
||||
})
|
||||
"fully_perform",
|
||||
span,
|
||||
)?;
|
||||
output.error_info = error_info;
|
||||
if let Some(constraints) = output.constraints {
|
||||
region_constraints
|
||||
.member_constraints
|
||||
.extend(constraints.member_constraints.iter().cloned());
|
||||
region_constraints.outlives.extend(constraints.outlives.iter().cloned());
|
||||
}
|
||||
output.constraints = if region_constraints.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(infcx.tcx.arena.alloc(region_constraints))
|
||||
};
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,8 @@ use crate::{Interner, PlaceholderLike, UniverseIndex};
|
||||
pub struct Canonical<I: Interner, V> {
|
||||
pub value: V,
|
||||
pub max_universe: UniverseIndex,
|
||||
// FIXME(lcnr, oli-obk): try moving this into the query inputs instead
|
||||
pub defining_opaque_types: I::DefiningOpaqueTypes,
|
||||
pub variables: I::CanonicalVars,
|
||||
}
|
||||
|
||||
@ -44,8 +46,8 @@ impl<I: Interner, V> Canonical<I, V> {
|
||||
/// let b: Canonical<I, (T, Ty<I>)> = a.unchecked_map(|v| (v, ty));
|
||||
/// ```
|
||||
pub fn unchecked_map<W>(self, map_op: impl FnOnce(V) -> W) -> Canonical<I, W> {
|
||||
let Canonical { max_universe, variables, value } = self;
|
||||
Canonical { max_universe, variables, value: map_op(value) }
|
||||
let Canonical { defining_opaque_types, max_universe, variables, value } = self;
|
||||
Canonical { defining_opaque_types, max_universe, variables, value: map_op(value) }
|
||||
}
|
||||
|
||||
/// Allows you to map the `value` of a canonical while keeping the same set of
|
||||
@ -54,8 +56,8 @@ impl<I: Interner, V> Canonical<I, V> {
|
||||
/// **WARNING:** This function is very easy to mis-use, hence the name! See
|
||||
/// the comment of [Canonical::unchecked_map] for more details.
|
||||
pub fn unchecked_rebind<W>(self, value: W) -> Canonical<I, W> {
|
||||
let Canonical { max_universe, variables, value: _ } = self;
|
||||
Canonical { max_universe, variables, value }
|
||||
let Canonical { defining_opaque_types, max_universe, variables, value: _ } = self;
|
||||
Canonical { defining_opaque_types, max_universe, variables, value }
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,28 +65,32 @@ impl<I: Interner, V: Eq> Eq for Canonical<I, V> {}
|
||||
|
||||
impl<I: Interner, V: PartialEq> PartialEq for Canonical<I, V> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.value == other.value
|
||||
&& self.max_universe == other.max_universe
|
||||
&& self.variables == other.variables
|
||||
let Self { value, max_universe, variables, defining_opaque_types } = self;
|
||||
*value == other.value
|
||||
&& *max_universe == other.max_universe
|
||||
&& *variables == other.variables
|
||||
&& *defining_opaque_types == other.defining_opaque_types
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, V: fmt::Display> fmt::Display for Canonical<I, V> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Self { value, max_universe, variables, defining_opaque_types } = self;
|
||||
write!(
|
||||
f,
|
||||
"Canonical {{ value: {}, max_universe: {:?}, variables: {:?} }}",
|
||||
self.value, self.max_universe, self.variables
|
||||
"Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?}, defining_opaque_types: {defining_opaque_types:?} }}",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I: Interner, V: fmt::Debug> fmt::Debug for Canonical<I, V> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
let Self { value, max_universe, variables, defining_opaque_types } = self;
|
||||
f.debug_struct("Canonical")
|
||||
.field("value", &self.value)
|
||||
.field("max_universe", &self.max_universe)
|
||||
.field("variables", &self.variables)
|
||||
.field("value", &value)
|
||||
.field("max_universe", &max_universe)
|
||||
.field("variables", &variables)
|
||||
.field("defining_opaque_types", &defining_opaque_types)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@ -100,6 +106,7 @@ where
|
||||
value: self.value.try_fold_with(folder)?,
|
||||
max_universe: self.max_universe.try_fold_with(folder)?,
|
||||
variables: self.variables.try_fold_with(folder)?,
|
||||
defining_opaque_types: self.defining_opaque_types,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -109,9 +116,11 @@ where
|
||||
I::CanonicalVars: TypeVisitable<I>,
|
||||
{
|
||||
fn visit_with<F: TypeVisitor<I>>(&self, folder: &mut F) -> F::Result {
|
||||
try_visit!(self.value.visit_with(folder));
|
||||
try_visit!(self.max_universe.visit_with(folder));
|
||||
self.variables.visit_with(folder)
|
||||
let Self { value, max_universe, variables, defining_opaque_types } = self;
|
||||
try_visit!(value.visit_with(folder));
|
||||
try_visit!(max_universe.visit_with(folder));
|
||||
try_visit!(defining_opaque_types.visit_with(folder));
|
||||
variables.visit_with(folder)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,10 @@ impl<I: Interner> InferCtxtLike for NoInfcx<I> {
|
||||
fn probe_ct_var(&self, _vid: ConstVid) -> Option<I::Const> {
|
||||
None
|
||||
}
|
||||
|
||||
fn defining_opaque_types(&self) -> <Self::Interner as Interner>::DefiningOpaqueTypes {
|
||||
Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
pub trait DebugWithInfcx<I: Interner>: fmt::Debug {
|
||||
|
@ -37,4 +37,6 @@ pub trait InferCtxtLike {
|
||||
|
||||
/// Resolve `ConstVid` to its inferred type, if it has been equated with a non-infer type.
|
||||
fn probe_ct_var(&self, vid: ConstVid) -> Option<<Self::Interner as Interner>::Const>;
|
||||
|
||||
fn defining_opaque_types(&self) -> <Self::Interner as Interner>::DefiningOpaqueTypes;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ use crate::{
|
||||
|
||||
pub trait Interner: Sized + Copy {
|
||||
type DefId: Copy + Debug + Hash + Eq;
|
||||
type DefiningOpaqueTypes: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
||||
type AdtDef: Copy + Debug + Hash + Eq;
|
||||
|
||||
type GenericArgs: Copy
|
||||
|
@ -4132,7 +4132,6 @@ ui/type-alias-impl-trait/issue-52843.rs
|
||||
ui/type-alias-impl-trait/issue-53092-2.rs
|
||||
ui/type-alias-impl-trait/issue-53092.rs
|
||||
ui/type-alias-impl-trait/issue-53096.rs
|
||||
ui/type-alias-impl-trait/issue-53398-cyclic-types.rs
|
||||
ui/type-alias-impl-trait/issue-53598.rs
|
||||
ui/type-alias-impl-trait/issue-53678-coroutine-and-const-fn.rs
|
||||
ui/type-alias-impl-trait/issue-55099-lifetime-inference.rs
|
||||
|
@ -1,36 +1,36 @@
|
||||
// MIR for `address_of_reborrow` after SimplifyCfg-initial
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:8:5: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:10:5: 10:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:19:5: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:21:5: 21:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:29:5: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:31:5: 31:23, inferred_ty: *mut dyn std::marker::Send
|
||||
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
|
||||
| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
|
||||
| 0: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:8:5: 8:18, inferred_ty: *const [i32; 10]
|
||||
| 1: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:10:5: 10:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 2: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 3: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:14:12: 14:20, inferred_ty: *const [i32; 10]
|
||||
| 4: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 5: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:15:12: 15:28, inferred_ty: *const [i32; 10]
|
||||
| 6: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 7: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:16:12: 16:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 8: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 9: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:17:12: 17:24, inferred_ty: *const [i32]
|
||||
| 10: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:19:5: 19:18, inferred_ty: *const [i32; 10]
|
||||
| 11: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:21:5: 21:25, inferred_ty: *const dyn std::marker::Send
|
||||
| 12: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 13: user_ty: Canonical { value: Ty(*const ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:24:12: 24:20, inferred_ty: *const [i32; 10]
|
||||
| 14: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 15: user_ty: Canonical { value: Ty(*const [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:25:12: 25:28, inferred_ty: *const [i32; 10]
|
||||
| 16: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 17: user_ty: Canonical { value: Ty(*const dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:26:12: 26:27, inferred_ty: *const dyn std::marker::Send
|
||||
| 18: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 19: user_ty: Canonical { value: Ty(*const [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:27:12: 27:24, inferred_ty: *const [i32]
|
||||
| 20: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:29:5: 29:16, inferred_ty: *mut [i32; 10]
|
||||
| 21: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:31:5: 31:23, inferred_ty: *mut dyn std::marker::Send
|
||||
| 22: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 23: user_ty: Canonical { value: Ty(*mut ^0), max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:34:12: 34:18, inferred_ty: *mut [i32; 10]
|
||||
| 24: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 25: user_ty: Canonical { value: Ty(*mut [i32; 10]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:35:12: 35:26, inferred_ty: *mut [i32; 10]
|
||||
| 26: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 27: user_ty: Canonical { value: Ty(*mut dyn std::marker::Send), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/address_of.rs:36:12: 36:25, inferred_ty: *mut dyn std::marker::Send
|
||||
| 28: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
|
||||
| 29: user_ty: Canonical { value: Ty(*mut [i32]), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/address_of.rs:37:12: 37:22, inferred_ty: *mut [i32]
|
||||
|
|
||||
fn address_of_reborrow() -> () {
|
||||
let mut _0: ();
|
||||
|
@ -1,8 +1,8 @@
|
||||
// MIR for `main` after SimplifyCfg-initial
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
|
||||
| 1: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
|
||||
| 0: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
|
||||
| 1: user_ty: Canonical { value: Ty(std::option::Option<std::boxed::Box<u32>>), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/basic_assignment.rs:38:17: 38:33, inferred_ty: std::option::Option<std::boxed::Box<u32>>
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
@ -1,8 +1,8 @@
|
||||
// MIR for `main` after built
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
|
||||
| 1: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
|
||||
| 0: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
|
||||
| 1: user_ty: Canonical { value: Ty(std::option::Option<u8>), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_101867.rs:4:12: 4:22, inferred_ty: std::option::Option<u8>
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
@ -1,10 +1,10 @@
|
||||
// MIR for `main` after built
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
|
||||
| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
|
||||
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
| 0: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
|
||||
| 1: user_ty: Canonical { value: Ty(*mut Test), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:15:14: 15:23, inferred_ty: *mut Test
|
||||
| 2: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
| 3: user_ty: Canonical { value: Ty(&&&&*mut Test), max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }, CanonicalVarInfo { kind: Region(U0) }], defining_opaque_types: [] }, span: $DIR/receiver_ptr_mutability.rs:19:18: 19:31, inferred_ty: &&&&*mut Test
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
@ -1,8 +1,8 @@
|
||||
// MIR for `main` after built
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void
|
||||
| 1: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void
|
||||
| 0: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void
|
||||
| 1: user_ty: Canonical { value: Ty(Void), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_72181_1.rs:17:12: 17:16, inferred_ty: Void
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
@ -1,8 +1,8 @@
|
||||
// MIR for `main` after built
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &'static [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &'static [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
@ -1,8 +1,8 @@
|
||||
// MIR for `main` after built
|
||||
|
||||
| User Type Annotations
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &'static [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 0: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [&*b"AAAA"], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:13:16: 13:46, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
| 1: user_ty: Canonical { value: TypeOf(DefId(0:3 ~ issue_99325[d56d]::function_with_bytes), UserArgs { args: [UnevaluatedConst { def: DefId(0:8 ~ issue_99325[d56d]::main::{constant#1}), args: [] }: &'static [u8; 4_usize]], user_self_ty: None }), max_universe: U0, variables: [], defining_opaque_types: [] }, span: $DIR/issue_99325.rs:14:16: 14:68, inferred_ty: fn() -> &'static [u8] {function_with_bytes::<&*b"AAAA">}
|
||||
|
|
||||
fn main() -> () {
|
||||
let mut _0: ();
|
||||
|
27
tests/ui/impl-trait/different_where_bounds.rs
Normal file
27
tests/ui/impl-trait/different_where_bounds.rs
Normal file
@ -0,0 +1,27 @@
|
||||
//! This test checks that the param env canonicalization cache
|
||||
//! does not end up with inconsistent values.
|
||||
|
||||
//@ check-pass
|
||||
|
||||
pub fn poison1() -> impl Sized
|
||||
where
|
||||
(): 'static,
|
||||
{
|
||||
}
|
||||
pub fn poison2() -> impl Sized
|
||||
where
|
||||
(): 'static,
|
||||
{
|
||||
define_by_query((poison2, ()));
|
||||
}
|
||||
pub fn poison3() -> impl Sized
|
||||
where
|
||||
(): 'static,
|
||||
{
|
||||
}
|
||||
|
||||
trait Query {}
|
||||
impl<Out, F: Fn() -> Out> Query for (F, Out) {}
|
||||
fn define_by_query(_: impl Query) {}
|
||||
|
||||
fn main() {}
|
@ -1,23 +0,0 @@
|
||||
note: no errors encountered even though delayed bugs were created
|
||||
|
||||
note: those delayed bugs will now be shown as internal compiler errors
|
||||
|
||||
error: internal compiler error: {OpaqueTypeKey { def_id: DefId(rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }) } }}
|
||||
|
|
||||
=
|
||||
|
||||
|
||||
error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(foo::{opaque#0}) }))), bound_vars: [] } } }
|
||||
--> $DIR/equality-in-canonical-query.rs:21:5
|
||||
|
|
||||
LL | same_output(foo, rpit);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
--> $DIR/equality-in-canonical-query.rs:21:5
|
||||
|
|
||||
LL | same_output(foo, rpit);
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
query stack during panic:
|
||||
end of query stack
|
@ -1,15 +1,6 @@
|
||||
// issue: #116877
|
||||
//@ revisions: sized clone
|
||||
//@[sized] check-pass
|
||||
//@[clone] known-bug: #108498
|
||||
//@[clone] failure-status: 101
|
||||
//@[clone] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
|
||||
//@[clone] normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> ""
|
||||
//@[clone] normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> ""
|
||||
//@[clone] normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> ""
|
||||
//@[clone] normalize-stderr-test: "(?m)note: delayed at.*$" -> ""
|
||||
//@[clone] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
|
||||
//@[clone] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
|
||||
//@ check-pass
|
||||
|
||||
#[cfg(sized)] fn rpit() -> impl Sized {}
|
||||
#[cfg(clone)] fn rpit() -> impl Clone {}
|
||||
|
32
tests/ui/impl-trait/nested-hkl-lifetime.rs
Normal file
32
tests/ui/impl-trait/nested-hkl-lifetime.rs
Normal file
@ -0,0 +1,32 @@
|
||||
//@ check-pass
|
||||
|
||||
use std::iter::FromIterator;
|
||||
|
||||
struct DynamicAlt<P>(P);
|
||||
|
||||
impl<P> FromIterator<P> for DynamicAlt<P> {
|
||||
fn from_iter<T: IntoIterator<Item = P>>(_iter: T) -> Self {
|
||||
loop {}
|
||||
}
|
||||
}
|
||||
|
||||
fn owned_context<I, F>(_: F) -> impl FnMut(I) -> I {
|
||||
|i| i
|
||||
}
|
||||
|
||||
trait Parser<I> {}
|
||||
|
||||
impl<T, I> Parser<I> for T where T: FnMut(I) -> I {}
|
||||
|
||||
fn alt<I, P: Parser<I>>(_: DynamicAlt<P>) -> impl FnMut(I) -> I {
|
||||
|i| i
|
||||
}
|
||||
|
||||
fn rule_to_parser<'c>() -> impl Parser<&'c str> {
|
||||
move |input| {
|
||||
let v: Vec<()> = vec![];
|
||||
alt(v.iter().map(|()| owned_context(rule_to_parser())).collect::<DynamicAlt<_>>())(input)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -44,7 +44,7 @@ fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized
|
||||
|
||||
// This should resolve.
|
||||
fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
|
||||
//~^ ERROR type annotations needed: cannot satisfy `for<'a> &'a (): Qux<'b>`
|
||||
//~^ ERROR the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied
|
||||
|
||||
// This should resolve.
|
||||
fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {}
|
||||
|
@ -86,13 +86,12 @@ note: lifetime declared here
|
||||
LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {}
|
||||
| ^^
|
||||
|
||||
error[E0283]: type annotations needed: cannot satisfy `for<'a> &'a (): Qux<'b>`
|
||||
error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied
|
||||
--> $DIR/nested-rpit-hrtb.rs:46:79
|
||||
|
|
||||
LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {}
|
||||
| ^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()`
|
||||
|
|
||||
= note: cannot satisfy `for<'a> &'a (): Qux<'b>`
|
||||
= help: the trait `Qux<'_>` is implemented for `()`
|
||||
= help: for that trait implementation, expected `()`, found `&'a ()`
|
||||
|
||||
@ -125,5 +124,5 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si
|
||||
|
||||
error: aborting due to 11 previous errors
|
||||
|
||||
Some errors have detailed explanations: E0261, E0277, E0283, E0657.
|
||||
Some errors have detailed explanations: E0261, E0277, E0657.
|
||||
For more information about an error, try `rustc --explain E0261`.
|
||||
|
@ -1,4 +1,4 @@
|
||||
error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ImpliedOutlivesBounds { ty: &'?2 mut StateContext<'?3, usize> } }
|
||||
error: internal compiler error: error performing operation: fully_perform
|
||||
--> $DIR/issue-80409.rs:49:30
|
||||
|
|
||||
LL | builder.state().on_entry(|_| {});
|
||||
|
@ -1,11 +0,0 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
//@ check-pass
|
||||
|
||||
type Foo = impl Fn() -> Foo;
|
||||
|
||||
fn foo() -> Foo {
|
||||
foo
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -1,23 +0,0 @@
|
||||
note: no errors encountered even though delayed bugs were created
|
||||
|
||||
note: those delayed bugs will now be shown as internal compiler errors
|
||||
|
||||
error: internal compiler error: {OpaqueTypeKey { def_id: DefId(get_rpit::{opaque#0}), args: [] }: OpaqueTypeDecl { hidden_type: OpaqueHiddenType { span: no-location (#0), ty: Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }) } }}
|
||||
|
|
||||
=
|
||||
|
||||
|
||||
error: internal compiler error: error performing ParamEnvAnd { param_env: ParamEnv { caller_bounds: [], reveal: UserFacing }, value: ProvePredicate { predicate: Binder { value: ProjectionPredicate(AliasTy { args: [FnDef(DefId(get_rpit), []), ()], def_id: DefId(ops::function::FnOnce::Output) }, Term::Ty(Alias(Opaque, AliasTy { args: [], def_id: DefId(Opaque::{opaque#0}) }))), bound_vars: [] } } }
|
||||
--> $DIR/rpit_tait_equality_in_canonical_query.rs:32:5
|
||||
|
|
||||
LL | query(get_rpit);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
|
||||
--> $DIR/rpit_tait_equality_in_canonical_query.rs:32:5
|
||||
|
|
||||
LL | query(get_rpit);
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
query stack during panic:
|
||||
end of query stack
|
@ -8,17 +8,7 @@
|
||||
//@ revisions: current next
|
||||
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||
//@[next] compile-flags: -Znext-solver
|
||||
//@[next] check-pass
|
||||
|
||||
//@[current] known-bug: #108498
|
||||
//@[current] failure-status: 101
|
||||
//@[current] normalize-stderr-test: "DefId\(.*?\]::" -> "DefId("
|
||||
//@[current] normalize-stderr-test: "(?m)note: we would appreciate a bug report.*\n\n" -> ""
|
||||
//@[current] normalize-stderr-test: "(?m)note: rustc.*running on.*\n\n" -> ""
|
||||
//@[current] normalize-stderr-test: "(?m)note: compiler flags.*\n\n" -> ""
|
||||
//@[current] normalize-stderr-test: "(?m)note: delayed at.*$" -> ""
|
||||
//@[current] normalize-stderr-test: "(?m)^ *\d+: .*\n" -> ""
|
||||
//@[current] normalize-stderr-test: "(?m)^ *at .*\n" -> ""
|
||||
//@ check-pass
|
||||
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
//@ known-bug: #109268
|
||||
|
||||
type Foo = impl Fn() -> Foo;
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
fn crash(x: Foo) -> Foo {
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
}
|
||||
fn main() {}
|
@ -0,0 +1,9 @@
|
||||
error[E0275]: overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-1.rs:6:21
|
||||
|
|
||||
LL | fn crash(x: Foo) -> Foo {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
@ -1,11 +1,11 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
//@ known-bug: #109268
|
||||
|
||||
pub trait Bar<T> {
|
||||
type Item;
|
||||
}
|
||||
|
||||
type Foo = impl Bar<Foo, Item = Foo>;
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
fn crash(x: Foo) -> Foo {
|
||||
x
|
@ -0,0 +1,9 @@
|
||||
error[E0275]: overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-2.rs:10:21
|
||||
|
|
||||
LL | fn crash(x: Foo) -> Foo {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
@ -0,0 +1,10 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
//@ known-bug: #109268
|
||||
|
||||
type Foo<'a> = impl Fn() -> Foo<'a>;
|
||||
|
||||
fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {}
|
@ -0,0 +1,9 @@
|
||||
error[E0275]: overflow evaluating the requirement `<Foo<'_> as FnOnce<()>>::Output == Foo<'a>`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-3.rs:6:40
|
||||
|
|
||||
LL | fn crash<'a>(_: &'a (), x: Foo<'a>) -> Foo<'a> {
|
||||
| ^^^^^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
@ -0,0 +1,16 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
//@ known-bug: trait-system-refactor-initiative#43
|
||||
|
||||
trait Id {
|
||||
type Assoc;
|
||||
}
|
||||
impl<T> Id for T {
|
||||
type Assoc = T;
|
||||
}
|
||||
|
||||
type Ty
|
||||
where
|
||||
Ty: Id<Assoc = Ty>,
|
||||
= impl Sized;
|
||||
fn define() -> Ty {}
|
||||
fn main() {}
|
@ -0,0 +1,39 @@
|
||||
error[E0275]: overflow evaluating the requirement `Ty: Id`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:11:1
|
||||
|
|
||||
LL | type Ty
|
||||
| ^^^^^^^
|
||||
|
|
||||
note: required by a bound on the type alias `Ty`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:13:9
|
||||
|
|
||||
LL | Ty: Id<Assoc = Ty>,
|
||||
| ^^^^^^^^^^^^^^ required by this bound
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `Ty: Id`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:15:19
|
||||
|
|
||||
LL | fn define() -> Ty {}
|
||||
| ^^
|
||||
|
|
||||
note: required by a bound on the type alias `Ty`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:13:9
|
||||
|
|
||||
LL | Ty: Id<Assoc = Ty>,
|
||||
| ^^^^^^^^^^^^^^ required by this bound
|
||||
|
||||
error[E0275]: overflow evaluating the requirement `Ty: Id`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:15:16
|
||||
|
|
||||
LL | fn define() -> Ty {}
|
||||
| ^^
|
||||
|
|
||||
note: required by a bound on the type alias `Ty`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error-4.rs:13:9
|
||||
|
|
||||
LL | Ty: Id<Assoc = Ty>,
|
||||
| ^^^^^^^^^^^^^^ required by this bound
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
@ -1,10 +0,0 @@
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12
|
||||
|
|
||||
LL | type Foo = impl Fn() -> Foo;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
@ -1,10 +0,0 @@
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12
|
||||
|
|
||||
LL | type Foo = impl Bar<Foo, Item = Foo>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
Loading…
Reference in New Issue
Block a user