mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Pass list of defineable opaque types into canonical queries
This commit is contained in:
parent
ea44ce059b
commit
19bd91d128
@ -133,6 +133,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
|
||||
|
@ -45,6 +45,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
let param_env = self.tcx.canonical_param_env_cache.get_or_insert(
|
||||
self.tcx,
|
||||
param_env,
|
||||
self.defining_use_anchor,
|
||||
query_state,
|
||||
|tcx, param_env, query_state| {
|
||||
// FIXME(#118965): We don't canonicalize the static lifetimes that appear in the
|
||||
@ -540,6 +541,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
max_universe: ty::UniverseIndex::ROOT,
|
||||
variables: List::empty(),
|
||||
value: (),
|
||||
defining_anchor: infcx.map(|i| i.defining_use_anchor).unwrap_or_default(),
|
||||
};
|
||||
Canonicalizer::canonicalize_with_base(
|
||||
base,
|
||||
@ -609,7 +611,12 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
|
||||
.max()
|
||||
.unwrap_or(ty::UniverseIndex::ROOT);
|
||||
|
||||
Canonical { max_universe, variables: canonical_variables, value: (base.value, out_value) }
|
||||
Canonical {
|
||||
max_universe,
|
||||
variables: canonical_variables,
|
||||
value: (base.value, out_value),
|
||||
defining_anchor: base.defining_anchor,
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a canonical variable replacing `kind` from the input,
|
||||
|
@ -243,13 +243,7 @@ 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.
|
||||
/// The `DefIds` of the opaque types that may have their hidden types constrained.
|
||||
///
|
||||
/// Its default value is `DefiningAnchor::Bind(&[])`, which means no opaque types may be defined.
|
||||
/// This way it is easier to catch errors that
|
||||
@ -401,6 +395,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_anchor(&self) -> DefiningAnchor<'tcx> {
|
||||
self.defining_use_anchor
|
||||
}
|
||||
}
|
||||
|
||||
/// See the `error_reporting` module for more details.
|
||||
@ -679,14 +677,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_opaque_type_inference(canonical.defining_anchor).build();
|
||||
let (value, args) = infcx.instantiate_canonical(span, canonical);
|
||||
(infcx, value, args)
|
||||
}
|
||||
|
@ -146,7 +146,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
DefiningAnchor::Bubble => {}
|
||||
}
|
||||
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
|
||||
@ -373,7 +372,6 @@ impl<'tcx> InferCtxt<'tcx> {
|
||||
#[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,
|
||||
};
|
||||
|
||||
|
@ -33,6 +33,7 @@ use std::ops::Index;
|
||||
|
||||
use crate::infer::MemberConstraint;
|
||||
use crate::mir::ConstraintCategory;
|
||||
use crate::traits::DefiningAnchor;
|
||||
use crate::ty::GenericArg;
|
||||
use crate::ty::{self, BoundVar, List, Region, Ty, TyCtxt, TypeFlags, TypeVisitableExt};
|
||||
|
||||
@ -153,11 +154,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,
|
||||
}
|
||||
@ -316,6 +312,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
key: ty::ParamEnv<'tcx>,
|
||||
defining_anchor: DefiningAnchor<'tcx>,
|
||||
state: &mut OriginalQueryValues<'tcx>,
|
||||
canonicalize_op: fn(
|
||||
TyCtxt<'tcx>,
|
||||
@ -330,6 +327,7 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
|
||||
max_universe: ty::UniverseIndex::ROOT,
|
||||
variables: List::empty(),
|
||||
value: key,
|
||||
defining_anchor,
|
||||
};
|
||||
}
|
||||
|
||||
@ -344,7 +342,8 @@ impl<'tcx> CanonicalParamEnvCache<'tcx> {
|
||||
*canonical
|
||||
}
|
||||
Entry::Vacant(e) => {
|
||||
let canonical = canonicalize_op(tcx, key, state);
|
||||
let mut canonical = canonicalize_op(tcx, key, state);
|
||||
canonical.defining_anchor = defining_anchor;
|
||||
let OriginalQueryValues { var_values, universe_map } = state;
|
||||
assert_eq!(universe_map.len(), 1);
|
||||
e.insert((canonical, tcx.arena.alloc_slice(var_values)));
|
||||
|
@ -338,10 +338,10 @@ 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
|
||||
#[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,10 +352,10 @@ macro_rules! define_callbacks {
|
||||
}
|
||||
};
|
||||
|
||||
// Ensure that values grow no larger than 64 bytes
|
||||
// Ensure that values grow no larger than 72 bytes
|
||||
#[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
|
||||
const _: () = {
|
||||
if mem::size_of::<Value<'static>>() > 64 {
|
||||
if mem::size_of::<Value<'static>>() > 72 {
|
||||
panic!("{}", concat!(
|
||||
"the query `",
|
||||
stringify!($name),
|
||||
|
@ -1004,6 +1004,7 @@ pub enum CodegenObligationError {
|
||||
/// 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)]
|
||||
#[derive(TyEncodable, TyDecodable)]
|
||||
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`.
|
||||
@ -1012,14 +1013,12 @@ pub enum DefiningAnchor<'tcx> {
|
||||
/// 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 Default for DefiningAnchor<'_> {
|
||||
fn default() -> Self {
|
||||
Self::Bind(ty::List::empty())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> DefiningAnchor<'tcx> {
|
||||
|
@ -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>,
|
||||
}
|
||||
|
||||
|
@ -84,6 +84,7 @@ use std::ops::{Bound, Deref};
|
||||
#[allow(rustc::usage_of_ty_tykind)]
|
||||
impl<'tcx> Interner for TyCtxt<'tcx> {
|
||||
type DefId = DefId;
|
||||
type DefiningAnchor = traits::DefiningAnchor<'tcx>;
|
||||
type AdtDef = ty::AdtDef<'tcx>;
|
||||
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
||||
type GenericArg = ty::GenericArg<'tcx>;
|
||||
|
@ -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_anchor = infcx.defining_anchor();
|
||||
Canonical { defining_anchor, 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 }),
|
||||
|
@ -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 {
|
||||
|
@ -316,5 +316,6 @@ fn response_no_constraints_raw<'tcx>(
|
||||
external_constraints: tcx.mk_external_constraints(ExternalConstraintsData::default()),
|
||||
certainty,
|
||||
},
|
||||
defining_anchor: Default::default(),
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,7 @@ use crate::{Interner, PlaceholderLike, UniverseIndex};
|
||||
pub struct Canonical<I: Interner, V> {
|
||||
pub value: V,
|
||||
pub max_universe: UniverseIndex,
|
||||
pub defining_anchor: I::DefiningAnchor,
|
||||
pub variables: I::CanonicalVars,
|
||||
}
|
||||
|
||||
@ -44,8 +45,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_anchor, max_universe, variables, value } = self;
|
||||
Canonical { defining_anchor, max_universe, variables, value: map_op(value) }
|
||||
}
|
||||
|
||||
/// Allows you to map the `value` of a canonical while keeping the same set of
|
||||
@ -54,8 +55,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_anchor, max_universe, variables, value: _ } = self;
|
||||
Canonical { defining_anchor, max_universe, variables, value }
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,30 +64,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 {
|
||||
let Self { value, max_universe, variables } = self;
|
||||
let Self { value, max_universe, variables, defining_anchor } = self;
|
||||
*value == other.value
|
||||
&& *max_universe == other.max_universe
|
||||
&& *variables == other.variables
|
||||
&& *defining_anchor == other.defining_anchor
|
||||
}
|
||||
}
|
||||
|
||||
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 } = self;
|
||||
let Self { value, max_universe, variables, defining_anchor } = self;
|
||||
write!(
|
||||
f,
|
||||
"Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?} }}",
|
||||
"Canonical {{ value: {value}, max_universe: {max_universe:?}, variables: {variables:?}, defining_anchor: {defining_anchor:?} }}",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
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 } = self;
|
||||
let Self { value, max_universe, variables, defining_anchor } = self;
|
||||
f.debug_struct("Canonical")
|
||||
.field("value", &value)
|
||||
.field("max_universe", &max_universe)
|
||||
.field("variables", &variables)
|
||||
.field("defining_anchor", &defining_anchor)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
@ -102,6 +105,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_anchor: self.defining_anchor,
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -111,9 +115,10 @@ where
|
||||
I::CanonicalVars: TypeVisitable<I>,
|
||||
{
|
||||
fn visit_with<F: TypeVisitor<I>>(&self, folder: &mut F) -> F::Result {
|
||||
let Self { value, max_universe, variables } = self;
|
||||
let Self { value, max_universe, variables, defining_anchor } = self;
|
||||
try_visit!(value.visit_with(folder));
|
||||
try_visit!(max_universe.visit_with(folder));
|
||||
try_visit!(defining_anchor.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_anchor(&self) -> <Self::Interner as Interner>::DefiningAnchor {
|
||||
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_anchor(&self) -> <Self::Interner as Interner>::DefiningAnchor;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ use crate::{
|
||||
|
||||
pub trait Interner: Sized + Copy {
|
||||
type DefId: Copy + Debug + Hash + Eq;
|
||||
type DefiningAnchor: Copy + Debug + Hash + Default + Eq + TypeVisitable<Self>;
|
||||
type AdtDef: Copy + Debug + Hash + Eq;
|
||||
|
||||
type GenericArgs: Copy
|
||||
|
@ -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 {}
|
||||
|
@ -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,10 +1,9 @@
|
||||
#![feature(type_alias_impl_trait)]
|
||||
|
||||
//@ check-pass
|
||||
|
||||
type Foo = impl Fn() -> Foo;
|
||||
|
||||
fn foo() -> Foo {
|
||||
//~^ ERROR: overflow
|
||||
foo
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,9 @@
|
||||
error[E0275]: overflow evaluating the requirement `<fn() -> Foo {foo} as FnOnce<()>>::Output == Foo`
|
||||
--> $DIR/issue-53398-cyclic-types.rs:5:13
|
||||
|
|
||||
LL | fn foo() -> Foo {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
@ -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)]
|
||||
|
||||
type Foo = impl Fn() -> Foo;
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
fn crash(x: Foo) -> Foo {
|
||||
//~^ ERROR: overflow
|
||||
x
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
}
|
||||
fn main() {}
|
||||
|
@ -1,10 +1,9 @@
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error.rs:3:12
|
||||
error[E0275]: overflow evaluating the requirement `<Foo as FnOnce<()>>::Output == Foo`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error.rs:5:21
|
||||
|
|
||||
LL | type Foo = impl Fn() -> Foo;
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||
LL | fn crash(x: Foo) -> Foo {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
@ -5,9 +5,9 @@ pub trait Bar<T> {
|
||||
}
|
||||
|
||||
type Foo = impl Bar<Foo, Item = Foo>;
|
||||
//~^ ERROR: unconstrained opaque type
|
||||
|
||||
fn crash(x: Foo) -> Foo {
|
||||
//~^ ERROR: overflow
|
||||
x
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,9 @@
|
||||
error: unconstrained opaque type
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error2.rs:7:12
|
||||
error[E0275]: overflow evaluating the requirement `<Foo as Bar<Foo>>::Item == Foo`
|
||||
--> $DIR/type-alias-impl-trait-with-cycle-error2.rs:9:21
|
||||
|
|
||||
LL | type Foo = impl Bar<Foo, Item = Foo>;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `Foo` must be used in combination with a concrete type within the same module
|
||||
LL | fn crash(x: Foo) -> Foo {
|
||||
| ^^^
|
||||
|
||||
error: aborting due to 1 previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0275`.
|
||||
|
Loading…
Reference in New Issue
Block a user