Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
8bd8f59
Bump windows-bindgen to 0.57
ChrisDenton Jun 10, 2024
93ee07c
Check that alias-relate terms are WF if reporting an error in alias-r…
compiler-errors Jun 12, 2024
ed1618d
MIR visitor: constant -> const_operand
RalfJung Jun 13, 2024
dcee529
smir: merge identical Constant and ConstOperand types
RalfJung Jun 13, 2024
267ba9a
Migrate `run-make/codegen-options-parsing` to `rmake.rs`
GuillaumeGomez Jun 14, 2024
8a8bbc0
Make Candidate generic over interner
compiler-errors Jun 14, 2024
c2e416c
Make proof tree probing generic
compiler-errors Jun 14, 2024
0562064
Correctly consider depth when visiting WF goals
compiler-errors Jun 14, 2024
58b065e
make uninitialized_error_reported a set of locals
beepster4096 Apr 28, 2024
a4eaf87
Migrate `run-make/dep-graph` to `rmake.rs`
GuillaumeGomez Jun 15, 2024
ea2ac34
trait_selection: remove extra words
jieyouxu Jun 15, 2024
b717aa1
tests/ui/lint: Move 19 tests to new `non-snake-case` subdir
Enselic Jun 15, 2024
4f83c1d
Rollup merge of #126229 - ChrisDenton:bindgen, r=Mark-Simulacrum
GuillaumeGomez Jun 15, 2024
709d862
Rollup merge of #126404 - compiler-errors:alias-relate-terms, r=lcnr
GuillaumeGomez Jun 15, 2024
be1d427
Rollup merge of #126410 - RalfJung:smir-const-operand, r=oli-obk
GuillaumeGomez Jun 15, 2024
1f076c2
Rollup merge of #126478 - GuillaumeGomez:migrate-run-make-codegen-opt…
GuillaumeGomez Jun 15, 2024
aa6fb1c
Rollup merge of #126496 - compiler-errors:more-generics, r=lcnr
GuillaumeGomez Jun 15, 2024
53364c3
Rollup merge of #126508 - beepster4096:minor_borrowck_cherrypick, r=c…
GuillaumeGomez Jun 15, 2024
38b3c9a
Rollup merge of #126517 - GuillaumeGomez:migrate-run-make-dep-graph, …
GuillaumeGomez Jun 15, 2024
b6311b3
Rollup merge of #126525 - jieyouxu:traitsel-docs, r=compiler-errors
GuillaumeGomez Jun 15, 2024
f788ea4
Rollup merge of #126526 - Enselic:non-snake-case, r=jieyouxu
GuillaumeGomez Jun 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions compiler/rustc_infer/src/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,10 @@ impl<'tcx> ty::InferCtxtLike for InferCtxt<'tcx> {
{
self.resolve_vars_if_possible(value)
}

fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
self.probe(|_| probe())
}
}

/// See the `error_reporting` module for more details.
Expand Down
99 changes: 50 additions & 49 deletions compiler/rustc_trait_selection/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
//! Code shared by trait and projection goals for candidate assembly.

use derivative::Derivative;
use rustc_hir::def_id::DefId;
use rustc_hir::LangItem;
use rustc_infer::infer::InferCtxt;
use rustc_infer::traits::query::NoSolution;
use rustc_middle::bug;
use rustc_middle::traits::solve::inspect::ProbeKind;
use rustc_middle::traits::solve::{
CandidateSource, CanonicalResponse, Certainty, Goal, MaybeCause, QueryResult,
};
use rustc_middle::traits::solve::{Certainty, Goal, MaybeCause, QueryResult};
use rustc_middle::traits::BuiltinImplSource;
use rustc_middle::ty::fast_reject::{SimplifiedType, TreatParams};
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{fast_reject, TypeFoldable};
use rustc_middle::ty::{TypeVisitableExt, Upcast};
use rustc_span::{ErrorGuaranteed, DUMMY_SP};
use std::fmt::Debug;
use rustc_type_ir::solve::{CandidateSource, CanonicalResponse};
use rustc_type_ir::Interner;

use crate::solve::GoalSource;
use crate::solve::{EvalCtxt, SolverMode};
Expand All @@ -26,10 +26,11 @@ pub(super) mod structural_traits;
///
/// It consists of both the `source`, which describes how that goal would be proven,
/// and the `result` when using the given `source`.
#[derive(Debug, Clone)]
pub(super) struct Candidate<'tcx> {
pub(super) source: CandidateSource<'tcx>,
pub(super) result: CanonicalResponse<'tcx>,
#[derive(Derivative)]
#[derivative(Debug(bound = ""), Clone(bound = ""))]
pub(super) struct Candidate<I: Interner> {
pub(super) source: CandidateSource<I>,
pub(super) result: CanonicalResponse<I>,
}

/// Methods used to assemble candidates for either trait or projection goals.
Expand All @@ -50,22 +51,22 @@ pub(super) trait GoalKind<'tcx>:
/// [`EvalCtxt::evaluate_added_goals_and_make_canonical_response`]).
fn probe_and_match_goal_against_assumption(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
source: CandidateSource<'tcx>,
source: CandidateSource<TyCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
assumption: ty::Clause<'tcx>,
then: impl FnOnce(&mut EvalCtxt<'_, InferCtxt<'tcx>>) -> QueryResult<'tcx>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// Consider a clause, which consists of a "assumption" and some "requirements",
/// to satisfy a goal. If the requirements hold, then attempt to satisfy our
/// goal by equating it with the assumption.
fn probe_and_consider_implied_clause(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
parent_source: CandidateSource<'tcx>,
parent_source: CandidateSource<TyCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
assumption: ty::Clause<'tcx>,
requirements: impl IntoIterator<Item = (GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)>,
) -> Result<Candidate<'tcx>, NoSolution> {
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
Self::probe_and_match_goal_against_assumption(ecx, parent_source, goal, assumption, |ecx| {
for (nested_source, goal) in requirements {
ecx.add_goal(nested_source, goal);
Expand All @@ -79,10 +80,10 @@ pub(super) trait GoalKind<'tcx>:
/// since they're not implied by the well-formedness of the object type.
fn probe_and_consider_object_bound_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
source: CandidateSource<'tcx>,
source: CandidateSource<TyCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
assumption: ty::Clause<'tcx>,
) -> Result<Candidate<'tcx>, NoSolution> {
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| {
let tcx = ecx.interner();
let ty::Dynamic(bounds, _, _) = *goal.predicate.self_ty().kind() else {
Expand All @@ -105,7 +106,7 @@ pub(super) trait GoalKind<'tcx>:
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
impl_def_id: DefId,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// If the predicate contained an error, we want to avoid emitting unnecessary trait
/// errors but still want to emit errors for other trait goals. We have some special
Expand All @@ -116,7 +117,7 @@ pub(super) trait GoalKind<'tcx>:
fn consider_error_guaranteed_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
guar: ErrorGuaranteed,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A type implements an `auto trait` if its components do as well.
///
Expand All @@ -125,13 +126,13 @@ pub(super) trait GoalKind<'tcx>:
fn consider_auto_trait_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A trait alias holds if the RHS traits and `where` clauses hold.
fn consider_trait_alias_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A type is `Sized` if its tail component is `Sized`.
///
Expand All @@ -140,7 +141,7 @@ pub(super) trait GoalKind<'tcx>:
fn consider_builtin_sized_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A type is `Copy` or `Clone` if its components are `Copy` or `Clone`.
///
Expand All @@ -149,50 +150,50 @@ pub(super) trait GoalKind<'tcx>:
fn consider_builtin_copy_clone_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A type is `PointerLike` if we can compute its layout, and that layout
/// matches the layout of `usize`.
fn consider_builtin_pointer_like_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A type is a `FnPtr` if it is of `FnPtr` type.
fn consider_builtin_fn_ptr_trait_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A callable type (a closure, fn def, or fn ptr) is known to implement the `Fn<A>`
/// family of traits where `A` is given by the signature of the type.
fn consider_builtin_fn_trait_candidates(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
kind: ty::ClosureKind,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// An async closure is known to implement the `AsyncFn<A>` family of traits
/// where `A` is given by the signature of the type.
fn consider_builtin_async_fn_trait_candidates(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
kind: ty::ClosureKind,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// Compute the built-in logic of the `AsyncFnKindHelper` helper trait, which
/// is used internally to delay computation for async closures until after
/// upvar analysis is performed in HIR typeck.
fn consider_builtin_async_fn_kind_helper_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// `Tuple` is implemented if the `Self` type is a tuple.
fn consider_builtin_tuple_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// `Pointee` is always implemented.
///
Expand All @@ -202,63 +203,63 @@ pub(super) trait GoalKind<'tcx>:
fn consider_builtin_pointee_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A coroutine (that comes from an `async` desugaring) is known to implement
/// `Future<Output = O>`, where `O` is given by the coroutine's return type
/// that was computed during type-checking.
fn consider_builtin_future_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A coroutine (that comes from a `gen` desugaring) is known to implement
/// `Iterator<Item = O>`, where `O` is given by the generator's yield type
/// that was computed during type-checking.
fn consider_builtin_iterator_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A coroutine (that comes from a `gen` desugaring) is known to implement
/// `FusedIterator`
fn consider_builtin_fused_iterator_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

fn consider_builtin_async_iterator_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// A coroutine (that doesn't come from an `async` or `gen` desugaring) is known to
/// implement `Coroutine<R, Yield = Y, Return = O>`, given the resume, yield,
/// and return types of the coroutine computed during type-checking.
fn consider_builtin_coroutine_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

fn consider_builtin_discriminant_kind_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

fn consider_builtin_async_destruct_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

fn consider_builtin_destruct_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

fn consider_builtin_transmute_candidate(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Result<Candidate<'tcx>, NoSolution>;
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution>;

/// Consider (possibly several) candidates to upcast or unsize a type to another
/// type, excluding the coercion of a sized type into a `dyn Trait`.
Expand All @@ -270,14 +271,14 @@ pub(super) trait GoalKind<'tcx>:
fn consider_structural_builtin_unsize_candidates(
ecx: &mut EvalCtxt<'_, InferCtxt<'tcx>>,
goal: Goal<'tcx, Self>,
) -> Vec<Candidate<'tcx>>;
) -> Vec<Candidate<TyCtxt<'tcx>>>;
}

impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
) -> Vec<Candidate<'tcx>> {
) -> Vec<Candidate<TyCtxt<'tcx>>> {
let Ok(normalized_self_ty) =
self.structurally_normalize_ty(goal.param_env, goal.predicate.self_ty())
else {
Expand Down Expand Up @@ -324,7 +325,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
pub(super) fn forced_ambiguity(
&mut self,
cause: MaybeCause,
) -> Result<Candidate<'tcx>, NoSolution> {
) -> Result<Candidate<TyCtxt<'tcx>>, NoSolution> {
// This may fail if `try_evaluate_added_goals` overflows because it
// fails to reach a fixpoint but ends up getting an error after
// running for some additional step.
Expand All @@ -340,7 +341,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn assemble_non_blanket_impl_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let tcx = self.interner();
let self_ty = goal.predicate.self_ty();
Expand Down Expand Up @@ -456,7 +457,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn assemble_blanket_impl_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let tcx = self.interner();
let trait_impls = tcx.trait_impls_of(goal.predicate.trait_def_id(tcx));
Expand All @@ -479,7 +480,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn assemble_builtin_impl_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let tcx = self.interner();
let trait_def_id = goal.predicate.trait_def_id(tcx);
Expand Down Expand Up @@ -552,7 +553,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn assemble_param_env_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
for (i, assumption) in goal.param_env.caller_bounds().iter().enumerate() {
candidates.extend(G::probe_and_consider_implied_clause(
Expand All @@ -569,7 +570,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn assemble_alias_bound_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates);
Expand All @@ -589,7 +590,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
&mut self,
self_ty: Ty<'tcx>,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let (kind, alias_ty) = match *self_ty.kind() {
ty::Bool
Expand Down Expand Up @@ -673,7 +674,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn assemble_object_bound_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let tcx = self.interner();
if !tcx.trait_def(goal.predicate.trait_def_id(tcx)).implement_via_object {
Expand Down Expand Up @@ -764,7 +765,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn assemble_coherence_unknowable_candidates<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let tcx = self.interner();

Expand Down Expand Up @@ -793,7 +794,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
fn discard_impls_shadowed_by_env<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
candidates: &mut Vec<Candidate<TyCtxt<'tcx>>>,
) {
let tcx = self.interner();
let trait_goal: Goal<'tcx, ty::TraitPredicate<'tcx>> =
Expand Down Expand Up @@ -841,7 +842,7 @@ impl<'tcx> EvalCtxt<'_, InferCtxt<'tcx>> {
#[instrument(level = "debug", skip(self), ret)]
pub(super) fn merge_candidates(
&mut self,
candidates: Vec<Candidate<'tcx>>,
candidates: Vec<Candidate<TyCtxt<'tcx>>>,
) -> QueryResult<'tcx> {
// First try merging all candidates. This is complete and fully sound.
let responses = candidates.iter().map(|c| c.result).collect::<Vec<_>>();
Expand Down
Loading