1
Fork 0

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:
bors 2024-10-16 17:58:25 +00:00
commit 7342830c05
77 changed files with 1254 additions and 560 deletions

View file

@ -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![];
};

View file

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

View file

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