Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 7 pull requests #120861

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0bfcafd
std::thread::available_parallelism merging linux/android/freebsd version
devnexen Feb 2, 2024
22d582a
For a rigid projection, recursively look at the self type's item bounds
compiler-errors Feb 1, 2024
548929d
Don't unnecessarily lower associated type bounds to impl trait
compiler-errors Feb 2, 2024
7a63d3f
Add tests for untested capabilities
compiler-errors Feb 2, 2024
7057188
make it recursive
compiler-errors Feb 7, 2024
f0d002b
Correctly generate path for non-local items in source code pages
GuillaumeGomez Feb 2, 2024
f3c2483
Add regression test for non local items link generation
GuillaumeGomez Feb 3, 2024
14e0dab
Unify item relative path computation in one function
GuillaumeGomez Feb 3, 2024
83f3bc4
Update jobserver-rs to 0.1.28
petrochenkov Feb 9, 2024
8b6b9c5
ast_lowering: Fix regression in `use ::{}` imports.
petrochenkov Feb 9, 2024
e59d9b1
Avoid a collection and iteration on empty passes
blyxyas Feb 9, 2024
4ef1790
tidy
blyxyas Feb 9, 2024
69a5264
Move some tests
c410-f3r Feb 9, 2024
ba5161f
Rollup merge of #120584 - compiler-errors:u, r=lcnr
matthiaskrgr Feb 9, 2024
a4c5094
Rollup merge of #120589 - devnexen:cpuaff_fbsd_upd, r=m-ou-se
matthiaskrgr Feb 9, 2024
d7251bb
Rollup merge of #120596 - GuillaumeGomez:jump-to-def-non-local-link, …
matthiaskrgr Feb 9, 2024
4cfee4b
Rollup merge of #120629 - c410-f3r:testsssssss, r=petrochenkov
matthiaskrgr Feb 9, 2024
dadff64
Rollup merge of #120846 - petrochenkov:jobs, r=oli-obk
matthiaskrgr Feb 9, 2024
9e5639e
Rollup merge of #120850 - petrochenkov:empimpres, r=cjgillot
matthiaskrgr Feb 9, 2024
0b6980b
Rollup merge of #120853 - blyxyas:no-collect, r=cjgillot
matthiaskrgr Feb 9, 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: 2 additions & 2 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2090,9 +2090,9 @@ dependencies = [

[[package]]
name = "jobserver"
version = "0.1.27"
version = "0.1.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d"
checksum = "ab46a6e9526ddef3ae7f787c06f0f2600639ba80ea3eade3d8e670a2230f51d6"
dependencies = [
"libc",
]
Expand Down
7 changes: 6 additions & 1 deletion compiler/rustc_ast_lowering/src/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
});
}

let path = if trees.is_empty() && !prefix.segments.is_empty() {
// Condition should match `build_reduced_graph_for_use_tree`.
let path = if trees.is_empty()
&& !(prefix.segments.is_empty()
|| prefix.segments.len() == 1
&& prefix.segments[0].ident.name == kw::PathRoot)
{
// For empty lists we need to lower the prefix so it is checked for things
// like stability later.
let res = self.lower_import_res(id, span);
Expand Down
24 changes: 11 additions & 13 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1092,24 +1092,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {

// Piggy-back on the `impl Trait` context to figure out the correct behavior.
let desugar_kind = match itctx {
// We are in the return position:
//
// fn foo() -> impl Iterator<Item: Debug>
//
// so desugar to
//
// fn foo() -> impl Iterator<Item = impl Debug>
ImplTraitContext::ReturnPositionOpaqueTy { .. }
| ImplTraitContext::TypeAliasesOpaqueTy { .. } => DesugarKind::ImplTrait,

// We are in the argument position, but within a dyn type:
// in an argument, RPIT, or TAIT, if we are within a dyn type:
//
// fn foo(x: dyn Iterator<Item: Debug>)
//
// so desugar to
// then desugar to:
//
// fn foo(x: dyn Iterator<Item = impl Debug>)
ImplTraitContext::Universal if self.is_in_dyn_type => DesugarKind::ImplTrait,
//
// This is because dyn traits must have all of their associated types specified.
ImplTraitContext::ReturnPositionOpaqueTy { .. }
| ImplTraitContext::TypeAliasesOpaqueTy { .. }
| ImplTraitContext::Universal
if self.is_in_dyn_type =>
{
DesugarKind::ImplTrait
}

ImplTraitContext::Disallowed(position) if self.is_in_dyn_type => {
DesugarKind::Error(position)
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ ar_archive_writer = "0.1.5"
bitflags = "2.4.1"
cc = "1.0.69"
itertools = "0.11"
jobserver = "0.1.27"
jobserver = "0.1.28"
pathdiff = "0.2.0"
regex = "1.4"
rustc_arena = { path = "../rustc_arena" }
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ either = "1.0"
elsa = "=1.7.1"
ena = "0.14.2"
indexmap = { version = "2.0.0" }
jobserver_crate = { version = "0.1.27", package = "jobserver" }
jobserver_crate = { version = "0.1.28", package = "jobserver" }
libc = "0.2"
measureme = "11"
rustc-hash = "1.1.0"
Expand Down
5 changes: 4 additions & 1 deletion compiler/rustc_data_structures/src/jobserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ static GLOBAL_CLIENT: LazyLock<Result<Client, String>> = LazyLock::new(|| {

if matches!(
error.kind(),
FromEnvErrorKind::NoEnvVar | FromEnvErrorKind::NoJobserver | FromEnvErrorKind::Unsupported
FromEnvErrorKind::NoEnvVar
| FromEnvErrorKind::NoJobserver
| FromEnvErrorKind::NegativeFd
| FromEnvErrorKind::Unsupported
) {
return Ok(default_client());
}
Expand Down
9 changes: 3 additions & 6 deletions compiler/rustc_lint/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -364,14 +364,11 @@ pub fn late_lint_mod<'tcx, T: LateLintPass<'tcx> + 'tcx>(
// Note: `passes` is often empty. In that case, it's faster to run
// `builtin_lints` directly rather than bundling it up into the
// `RuntimeCombinedLateLintPass`.
let mut passes: Vec<_> = unerased_lint_store(tcx.sess)
.late_module_passes
.iter()
.map(|mk_pass| (mk_pass)(tcx))
.collect();
if passes.is_empty() {
let late_module_passes = &unerased_lint_store(tcx.sess).late_module_passes;
if late_module_passes.is_empty() {
late_lint_mod_inner(tcx, module_def_id, context, builtin_lints);
} else {
let mut passes: Vec<_> = late_module_passes.iter().map(|mk_pass| (mk_pass)(tcx)).collect();
passes.push(Box::new(builtin_lints));
let pass = RuntimeCombinedLateLintPass { passes: &mut passes[..] };
late_lint_mod_inner(tcx, module_def_id, context, pass);
Expand Down
71 changes: 62 additions & 9 deletions compiler/rustc_trait_selection/src/solve/assembly/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,7 +548,27 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
) {
let alias_ty = match goal.predicate.self_ty().kind() {
let () = self.probe(|_| ProbeKind::NormalizedSelfTyAssembly).enter(|ecx| {
ecx.assemble_alias_bound_candidates_recur(goal.predicate.self_ty(), goal, candidates);
});
}

/// For some deeply nested `<T>::A::B::C::D` rigid associated type,
/// we should explore the item bounds for all levels, since the
/// `associated_type_bounds` feature means that a parent associated
/// type may carry bounds for a nested associated type.
///
/// If we have a projection, check that its self type is a rigid projection.
/// If so, continue searching by recursively calling after normalization.
// FIXME: This may recurse infinitely, but I can't seem to trigger it without
// hitting another overflow error something. Add a depth parameter needed later.
fn assemble_alias_bound_candidates_recur<G: GoalKind<'tcx>>(
&mut self,
self_ty: Ty<'tcx>,
goal: Goal<'tcx, G>,
candidates: &mut Vec<Candidate<'tcx>>,
) {
let (kind, alias_ty) = match *self_ty.kind() {
ty::Bool
| ty::Char
| ty::Int(_)
Expand All @@ -573,23 +593,56 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
| ty::Param(_)
| ty::Placeholder(..)
| ty::Infer(ty::IntVar(_) | ty::FloatVar(_))
| ty::Alias(ty::Inherent, _)
| ty::Alias(ty::Weak, _)
| ty::Error(_) => return,
ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
| ty::Bound(..) => bug!("unexpected self type for `{goal:?}`"),
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
ty::Alias(ty::Projection | ty::Opaque, alias_ty) => alias_ty,
ty::Infer(ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_)) | ty::Bound(..) => {
bug!("unexpected self type for `{goal:?}`")
}

ty::Infer(ty::TyVar(_)) => {
// If we hit infer when normalizing the self type of an alias,
// then bail with ambiguity. We should never encounter this on
// the *first* iteration of this recursive function.
if let Ok(result) =
self.evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS)
{
candidates.push(Candidate { source: CandidateSource::AliasBound, result });
}
return;
}

ty::Alias(kind @ (ty::Projection | ty::Opaque), alias_ty) => (kind, alias_ty),
ty::Alias(ty::Inherent | ty::Weak, _) => {
unreachable!("Weak and Inherent aliases should have been normalized away already")
}
};

for assumption in
self.tcx().item_bounds(alias_ty.def_id).instantiate(self.tcx(), alias_ty.args)
{
match G::consider_alias_bound_candidate(self, goal, assumption) {
Ok(result) => {
candidates.push(Candidate { source: CandidateSource::AliasBound, result })
candidates.push(Candidate { source: CandidateSource::AliasBound, result });
}
Err(NoSolution) => {}
}
}

if kind != ty::Projection {
return;
}

match self.try_normalize_ty(goal.param_env, alias_ty.self_ty()) {
// Recurse on the self type of the projection.
Some(next_self_ty) => {
self.assemble_alias_bound_candidates_recur(next_self_ty, goal, candidates);
}
// Bail if we overflow when normalizing, adding an ambiguous candidate.
None => {
if let Ok(result) =
self.evaluate_added_goals_and_make_canonical_response(Certainty::OVERFLOW)
{
candidates.push(Candidate { source: CandidateSource::AliasBound, result });
}
Err(NoSolution) => (),
}
}
}
Expand Down
59 changes: 36 additions & 23 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ use rustc_middle::ty::{self, Term, ToPredicate, Ty, TyCtxt};
use rustc_span::symbol::sym;

use std::collections::BTreeMap;
use std::ops::ControlFlow;

pub use rustc_middle::traits::Reveal;

Expand Down Expand Up @@ -1614,32 +1615,44 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
candidate_set: &mut ProjectionCandidateSet<'tcx>,
) {
debug!("assemble_candidates_from_trait_def(..)");
let mut ambiguous = false;
selcx.for_each_item_bound(
obligation.predicate.self_ty(),
|selcx, clause, _| {
let Some(clause) = clause.as_projection_clause() else {
return ControlFlow::Continue(());
};

let tcx = selcx.tcx();
// Check whether the self-type is itself a projection.
// If so, extract what we know from the trait and try to come up with a good answer.
let bounds = match *obligation.predicate.self_ty().kind() {
// Excluding IATs and type aliases here as they don't have meaningful item bounds.
ty::Alias(ty::Projection | ty::Opaque, ref data) => {
tcx.item_bounds(data.def_id).instantiate(tcx, data.args)
}
ty::Infer(ty::TyVar(_)) => {
// If the self-type is an inference variable, then it MAY wind up
// being a projected type, so induce an ambiguity.
candidate_set.mark_ambiguous();
return;
}
_ => return,
};
let is_match =
selcx.infcx.probe(|_| selcx.match_projection_projections(obligation, clause, true));

assemble_candidates_from_predicates(
selcx,
obligation,
candidate_set,
ProjectionCandidate::TraitDef,
bounds.iter(),
true,
match is_match {
ProjectionMatchesProjection::Yes => {
candidate_set.push_candidate(ProjectionCandidate::TraitDef(clause));

if !obligation.predicate.has_non_region_infer() {
// HACK: Pick the first trait def candidate for a fully
// inferred predicate. This is to allow duplicates that
// differ only in normalization.
return ControlFlow::Break(());
}
}
ProjectionMatchesProjection::Ambiguous => {
candidate_set.mark_ambiguous();
}
ProjectionMatchesProjection::No => {}
}

ControlFlow::Continue(())
},
// `ProjectionCandidateSet` is borrowed in the above closure,
// so just mark ambiguous outside of the closure.
|| ambiguous = true,
);

if ambiguous {
candidate_set.mark_ambiguous();
}
}

/// In the case of a trait object like
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,16 @@
//!
//! [rustc dev guide]:https://rustc-dev-guide.rust-lang.org/traits/resolution.html#candidate-assembly

use std::ops::ControlFlow;

use hir::def_id::DefId;
use hir::LangItem;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_infer::traits::ObligationCause;
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
use rustc_middle::ty::{self, Ty, TypeVisitableExt};
use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};

use crate::traits;
use crate::traits::query::evaluate_obligation::InferCtxtExt;
Expand Down Expand Up @@ -158,11 +161,50 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
_ => return,
}

let result = self
.infcx
.probe(|_| self.match_projection_obligation_against_definition_bounds(obligation));
self.infcx.probe(|_| {
let poly_trait_predicate = self.infcx.resolve_vars_if_possible(obligation.predicate);
let placeholder_trait_predicate =
self.infcx.enter_forall_and_leak_universe(poly_trait_predicate);
debug!(?placeholder_trait_predicate);

// The bounds returned by `item_bounds` may contain duplicates after
// normalization, so try to deduplicate when possible to avoid
// unnecessary ambiguity.
let mut distinct_normalized_bounds = FxHashSet::default();
self.for_each_item_bound::<!>(
placeholder_trait_predicate.self_ty(),
|selcx, bound, idx| {
let Some(bound) = bound.as_trait_clause() else {
return ControlFlow::Continue(());
};
if bound.polarity() != placeholder_trait_predicate.polarity {
return ControlFlow::Continue(());
}

candidates.vec.extend(result.into_iter().map(|idx| ProjectionCandidate(idx)));
selcx.infcx.probe(|_| {
match selcx.match_normalize_trait_ref(
obligation,
bound.to_poly_trait_ref(),
placeholder_trait_predicate.trait_ref,
) {
Ok(None) => {
candidates.vec.push(ProjectionCandidate(idx));
}
Ok(Some(normalized_trait))
if distinct_normalized_bounds.insert(normalized_trait) =>
{
candidates.vec.push(ProjectionCandidate(idx));
}
_ => {}
}
});

ControlFlow::Continue(())
},
// On ambiguity.
|| candidates.ambiguous = true,
);
});
}

/// Given an obligation like `<SomeTrait for T>`, searches the obligations that the caller
Expand Down
Loading
Loading