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:
bors 2024-04-08 23:01:50 +00:00
commit b234e44944
59 changed files with 469 additions and 387 deletions

View File

@ -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()

View File

@ -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");

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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 {

View File

@ -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(),

View File

@ -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,

View File

@ -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(

View File

@ -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()
}

View File

@ -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

View File

@ -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
}

View File

@ -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 {

View File

@ -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))
}
}

View File

@ -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>,
}

View File

@ -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.

View File

@ -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)>
{

View File

@ -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>,

View File

@ -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.

View File

@ -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) {

View File

@ -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)

View File

@ -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 }),

View File

@ -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(

View File

@ -316,5 +316,6 @@ fn response_no_constraints_raw<'tcx>(
external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
certainty,
},
defining_opaque_types: Default::default(),
}
}

View File

@ -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);
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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: ();

View File

@ -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: ();

View File

@ -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: ();

View File

@ -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: ();

View File

@ -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: ();

View File

@ -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: ();

View File

@ -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: ();

View 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() {}

View File

@ -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

View File

@ -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 {}

View 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() {}

View File

@ -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> {}

View File

@ -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`.

View File

@ -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(|_| {});

View File

@ -1,11 +0,0 @@
#![feature(type_alias_impl_trait)]
//@ check-pass
type Foo = impl Fn() -> Foo;
fn foo() -> Foo {
foo
}
fn main() {}

View File

@ -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

View File

@ -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)]

View File

@ -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() {}

View File

@ -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`.

View File

@ -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

View File

@ -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`.

View File

@ -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() {}

View File

@ -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`.

View File

@ -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() {}

View File

@ -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`.

View File

@ -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

View File

@ -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