Auto merge of #131792 - matthiaskrgr:rollup-480nwg4, r=matthiaskrgr
Rollup of 8 pull requests Successful merges: - #130822 (Add `from_ref` and `from_mut` constructors to `core::ptr::NonNull`.) - #131381 (Implement edition 2024 match ergonomics restrictions) - #131594 (rustdoc: Rename "object safe" to "dyn compatible") - #131686 (Add fast-path when computing the default visibility) - #131699 (Try to improve error messages involving aliases in the solver) - #131757 (Ignore lint-non-snake-case-crate#proc_macro_ on targets without unwind) - #131783 (Fix explicit_iter_loop in rustc_serialize) - #131788 (Fix mismatched quotation mark) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
7342830c05
77 changed files with 1254 additions and 560 deletions
|
@ -6,6 +6,7 @@ use derive_where::derive_where;
|
|||
use rustc_type_ir::fold::TypeFoldable;
|
||||
use rustc_type_ir::inherent::*;
|
||||
use rustc_type_ir::lang_items::TraitSolverLangItem;
|
||||
use rustc_type_ir::solve::inspect;
|
||||
use rustc_type_ir::visit::TypeVisitableExt as _;
|
||||
use rustc_type_ir::{self as ty, Interner, Upcast as _, elaborate};
|
||||
use tracing::{debug, instrument};
|
||||
|
@ -288,6 +289,25 @@ where
|
|||
let Ok(normalized_self_ty) =
|
||||
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
|
||||
else {
|
||||
// FIXME: We register a fake candidate when normalization fails so that
|
||||
// we can point at the reason for *why*. I'm tempted to say that this
|
||||
// is the wrong way to do this, though.
|
||||
let result =
|
||||
self.probe(|&result| inspect::ProbeKind::RigidAlias { result }).enter(|this| {
|
||||
let normalized_ty = this.next_ty_infer();
|
||||
let alias_relate_goal = Goal::new(
|
||||
this.cx(),
|
||||
goal.param_env,
|
||||
ty::PredicateKind::AliasRelate(
|
||||
goal.predicate.self_ty().into(),
|
||||
normalized_ty.into(),
|
||||
ty::AliasRelationDirection::Equate,
|
||||
),
|
||||
);
|
||||
this.add_goal(GoalSource::AliasWellFormed, alias_relate_goal);
|
||||
this.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
|
||||
});
|
||||
assert_eq!(result, Err(NoSolution));
|
||||
return vec![];
|
||||
};
|
||||
|
||||
|
|
|
@ -983,7 +983,7 @@ where
|
|||
hidden_ty,
|
||||
&mut goals,
|
||||
);
|
||||
self.add_goals(GoalSource::Misc, goals);
|
||||
self.add_goals(GoalSource::AliasWellFormed, goals);
|
||||
}
|
||||
|
||||
// Do something for each opaque/hidden pair defined with `def_id` in the
|
||||
|
|
|
@ -15,7 +15,7 @@ use crate::solve::assembly::{self, Candidate};
|
|||
use crate::solve::inspect::ProbeKind;
|
||||
use crate::solve::{
|
||||
BuiltinImplSource, CandidateSource, Certainty, EvalCtxt, Goal, GoalSource, MaybeCause,
|
||||
NoSolution, QueryResult,
|
||||
NoSolution, QueryResult, Reveal,
|
||||
};
|
||||
|
||||
impl<D, I> EvalCtxt<'_, D>
|
||||
|
@ -37,13 +37,64 @@ where
|
|||
match normalize_result {
|
||||
Ok(res) => Ok(res),
|
||||
Err(NoSolution) => {
|
||||
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
|
||||
self.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
|
||||
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
self.probe(|&result| ProbeKind::RigidAlias { result }).enter(|this| {
|
||||
let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
|
||||
this.add_rigid_constraints(param_env, alias)?;
|
||||
this.relate_rigid_alias_non_alias(param_env, alias, ty::Invariant, term)?;
|
||||
this.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Register any obligations that are used to validate that an alias should be
|
||||
/// treated as rigid.
|
||||
///
|
||||
/// An alias may be considered rigid if it fails normalization, but we also don't
|
||||
/// want to consider aliases that are not well-formed to be rigid simply because
|
||||
/// they fail normalization.
|
||||
///
|
||||
/// For example, some `<T as Trait>::Assoc` where `T: Trait` does not hold, or an
|
||||
/// opaque type whose hidden type doesn't actually satisfy the opaque item bounds.
|
||||
fn add_rigid_constraints(
|
||||
&mut self,
|
||||
param_env: I::ParamEnv,
|
||||
rigid_alias: ty::AliasTerm<I>,
|
||||
) -> Result<(), NoSolution> {
|
||||
let cx = self.cx();
|
||||
match rigid_alias.kind(cx) {
|
||||
// Projections are rigid only if their trait ref holds,
|
||||
// and the GAT where-clauses hold.
|
||||
ty::AliasTermKind::ProjectionTy | ty::AliasTermKind::ProjectionConst => {
|
||||
let trait_ref = rigid_alias.trait_ref(cx);
|
||||
self.add_goal(GoalSource::AliasWellFormed, Goal::new(cx, param_env, trait_ref));
|
||||
Ok(())
|
||||
}
|
||||
ty::AliasTermKind::OpaqueTy => {
|
||||
match param_env.reveal() {
|
||||
// In user-facing mode, paques are only rigid if we may not define it.
|
||||
Reveal::UserFacing => {
|
||||
if rigid_alias
|
||||
.def_id
|
||||
.as_local()
|
||||
.is_some_and(|def_id| self.can_define_opaque_ty(def_id))
|
||||
{
|
||||
Err(NoSolution)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
// Opaques are never rigid in reveal-all mode.
|
||||
Reveal::All => Err(NoSolution),
|
||||
}
|
||||
}
|
||||
// FIXME(generic_const_exprs): we would need to support generic consts here
|
||||
ty::AliasTermKind::UnevaluatedConst => Err(NoSolution),
|
||||
// Inherent and weak types are never rigid. This type must not be well-formed.
|
||||
ty::AliasTermKind::WeakTy | ty::AliasTermKind::InherentTy => Err(NoSolution),
|
||||
}
|
||||
}
|
||||
|
||||
/// Normalize the given alias by at least one step. If the alias is rigid, this
|
||||
/// returns `NoSolution`.
|
||||
#[instrument(level = "trace", skip(self), ret)]
|
||||
|
@ -124,6 +175,7 @@ where
|
|||
ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
|
||||
|
||||
// Add GAT where clauses from the trait's definition
|
||||
// FIXME: We don't need these, since these are the type's own WF obligations.
|
||||
ecx.add_goals(
|
||||
GoalSource::Misc,
|
||||
cx.own_predicates_of(goal.predicate.def_id())
|
||||
|
@ -179,7 +231,8 @@ where
|
|||
.map(|pred| goal.with(cx, pred));
|
||||
ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
|
||||
|
||||
// Add GAT where clauses from the trait's definition
|
||||
// Add GAT where clauses from the trait's definition.
|
||||
// FIXME: We don't need these, since these are the type's own WF obligations.
|
||||
ecx.add_goals(
|
||||
GoalSource::Misc,
|
||||
cx.own_predicates_of(goal.predicate.def_id())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue