Skip to content

Commit e098eb1

Browse files
committed
Auto merge of rust-lang#107143 - compiler-errors:rollup-zabvmo5, r=compiler-errors
Rollup of 9 pull requests Successful merges: - rust-lang#104154 (Change `bindings_with_variant_name` to deny-by-default) - rust-lang#104347 (diagnostics: suggest changing `s@self::{macro}`@::macro`` for exported) - rust-lang#104672 (Unify stable and unstable sort implementations in same core module) - rust-lang#107048 (check for x version updates) - rust-lang#107061 (Implement some more new solver candidates and fix some bugs) - rust-lang#107095 (rustdoc: remove redundant CSS selector `.sidebar .current`) - rust-lang#107112 (Fix typo in opaque_types.rs) - rust-lang#107124 (fix check macro expansion) - rust-lang#107131 (rustdoc: use CSS inline layout for radio line instead of flexbox) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0726909 + 34d4df5 commit e098eb1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1086
-410
lines changed

Cargo.lock

+1
Original file line numberDiff line numberDiff line change
@@ -5608,6 +5608,7 @@ dependencies = [
56085608
"lazy_static",
56095609
"miropt-test-tools",
56105610
"regex",
5611+
"semver",
56115612
"termcolor",
56125613
"walkdir",
56135614
]

compiler/rustc_index/src/vec.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,12 @@ impl<I: Idx, T> IndexVec<I, T> {
207207
&'a mut self,
208208
range: R,
209209
) -> impl Iterator<Item = (I, T)> + 'a {
210-
self.raw.drain(range).enumerate().map(|(n, t)| (I::new(n), t))
210+
let begin = match range.start_bound() {
211+
std::ops::Bound::Included(i) => *i,
212+
std::ops::Bound::Excluded(i) => i.checked_add(1).unwrap(),
213+
std::ops::Bound::Unbounded => 0,
214+
};
215+
self.raw.drain(range).enumerate().map(move |(n, t)| (I::new(begin + n), t))
211216
}
212217

213218
#[inline]

compiler/rustc_infer/src/infer/opaque_types.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -479,7 +479,7 @@ where
479479
}
480480

481481
ty::Alias(ty::Opaque, ty::AliasTy { def_id, ref substs, .. }) => {
482-
// Skip lifetime paramters that are not captures.
482+
// Skip lifetime parameters that are not captures.
483483
let variances = self.tcx.variances_of(*def_id);
484484

485485
for (v, s) in std::iter::zip(variances, substs.iter()) {
@@ -492,7 +492,7 @@ where
492492
ty::Alias(ty::Projection, proj)
493493
if self.tcx.def_kind(proj.def_id) == DefKind::ImplTraitPlaceholder =>
494494
{
495-
// Skip lifetime paramters that are not captures.
495+
// Skip lifetime parameters that are not captures.
496496
let variances = self.tcx.variances_of(proj.def_id);
497497

498498
for (v, s) in std::iter::zip(variances, proj.substs.iter()) {

compiler/rustc_lint_defs/src/builtin.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,7 @@ declare_lint! {
708708
///
709709
/// ### Example
710710
///
711-
/// ```rust
711+
/// ```rust,compile_fail
712712
/// pub enum Enum {
713713
/// Foo,
714714
/// Bar,
@@ -743,7 +743,7 @@ declare_lint! {
743743
/// [identifier pattern]: https://doc.rust-lang.org/reference/patterns.html#identifier-patterns
744744
/// [path pattern]: https://doc.rust-lang.org/reference/patterns.html#path-patterns
745745
pub BINDINGS_WITH_VARIANT_NAME,
746-
Warn,
746+
Deny,
747747
"detects pattern bindings with the same name as one of the matched variants"
748748
}
749749

compiler/rustc_resolve/src/diagnostics.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -2125,9 +2125,15 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
21252125

21262126
let source_map = self.r.session.source_map();
21272127

2128+
// Make sure this is actually crate-relative.
2129+
let is_definitely_crate = import
2130+
.module_path
2131+
.first()
2132+
.map_or(false, |f| f.ident.name != kw::SelfLower && f.ident.name != kw::Super);
2133+
21282134
// Add the import to the start, with a `{` if required.
21292135
let start_point = source_map.start_point(after_crate_name);
2130-
if let Ok(start_snippet) = source_map.span_to_snippet(start_point) {
2136+
if is_definitely_crate && let Ok(start_snippet) = source_map.span_to_snippet(start_point) {
21312137
corrections.push((
21322138
start_point,
21332139
if has_nested {
@@ -2139,11 +2145,17 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
21392145
format!("{{{}, {}", import_snippet, start_snippet)
21402146
},
21412147
));
2142-
}
21432148

2144-
// Add a `};` to the end if nested, matching the `{` added at the start.
2145-
if !has_nested {
2146-
corrections.push((source_map.end_point(after_crate_name), "};".to_string()));
2149+
// Add a `};` to the end if nested, matching the `{` added at the start.
2150+
if !has_nested {
2151+
corrections.push((source_map.end_point(after_crate_name), "};".to_string()));
2152+
}
2153+
} else {
2154+
// If the root import is module-relative, add the import separately
2155+
corrections.push((
2156+
import.use_span.shrink_to_lo(),
2157+
format!("use {module_name}::{import_snippet};\n"),
2158+
));
21472159
}
21482160
}
21492161

compiler/rustc_trait_selection/src/solve/assembly.rs

+39-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Code shared by trait and projection goals for candidate assembly.
22
33
use super::infcx_ext::InferCtxtExt;
4-
use super::{CanonicalResponse, EvalCtxt, Goal, QueryResult};
4+
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
55
use rustc_hir::def_id::DefId;
66
use rustc_infer::traits::query::NoSolution;
77
use rustc_infer::traits::util::elaborate_predicates;
@@ -79,7 +79,7 @@ pub(super) enum CandidateSource {
7979
AliasBound(usize),
8080
}
8181

82-
pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy {
82+
pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy + Eq {
8383
fn self_ty(self) -> Ty<'tcx>;
8484

8585
fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self;
@@ -117,13 +117,43 @@ pub(super) trait GoalKind<'tcx>: TypeFoldable<'tcx> + Copy {
117117
ecx: &mut EvalCtxt<'_, 'tcx>,
118118
goal: Goal<'tcx, Self>,
119119
) -> QueryResult<'tcx>;
120+
121+
fn consider_builtin_pointer_sized_candidate(
122+
ecx: &mut EvalCtxt<'_, 'tcx>,
123+
goal: Goal<'tcx, Self>,
124+
) -> QueryResult<'tcx>;
125+
126+
fn consider_builtin_fn_trait_candidates(
127+
ecx: &mut EvalCtxt<'_, 'tcx>,
128+
goal: Goal<'tcx, Self>,
129+
kind: ty::ClosureKind,
130+
) -> QueryResult<'tcx>;
131+
132+
fn consider_builtin_tuple_candidate(
133+
ecx: &mut EvalCtxt<'_, 'tcx>,
134+
goal: Goal<'tcx, Self>,
135+
) -> QueryResult<'tcx>;
120136
}
121137

122138
impl<'tcx> EvalCtxt<'_, 'tcx> {
123139
pub(super) fn assemble_and_evaluate_candidates<G: GoalKind<'tcx>>(
124140
&mut self,
125141
goal: Goal<'tcx, G>,
126142
) -> Vec<Candidate<'tcx>> {
143+
debug_assert_eq!(goal, self.infcx.resolve_vars_if_possible(goal));
144+
145+
// HACK: `_: Trait` is ambiguous, because it may be satisfied via a builtin rule,
146+
// object bound, alias bound, etc. We are unable to determine this until we can at
147+
// least structually resolve the type one layer.
148+
if goal.predicate.self_ty().is_ty_var() {
149+
return vec![Candidate {
150+
source: CandidateSource::BuiltinImpl,
151+
result: self
152+
.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
153+
.unwrap(),
154+
}];
155+
}
156+
127157
let mut candidates = Vec::new();
128158

129159
self.assemble_candidates_after_normalizing_self_ty(goal, &mut candidates);
@@ -169,6 +199,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
169199
Ok((_, certainty)) => certainty,
170200
Err(NoSolution) => return,
171201
};
202+
let normalized_ty = self.infcx.resolve_vars_if_possible(normalized_ty);
172203

173204
// NOTE: Alternatively we could call `evaluate_goal` here and only have a `Normalized` candidate.
174205
// This doesn't work as long as we use `CandidateSource` in winnowing.
@@ -224,6 +255,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
224255
|| lang_items.clone_trait() == Some(trait_def_id)
225256
{
226257
G::consider_builtin_copy_clone_candidate(self, goal)
258+
} else if lang_items.pointer_sized() == Some(trait_def_id) {
259+
G::consider_builtin_pointer_sized_candidate(self, goal)
260+
} else if let Some(kind) = self.tcx().fn_trait_kind_from_def_id(trait_def_id) {
261+
G::consider_builtin_fn_trait_candidates(self, goal, kind)
262+
} else if lang_items.tuple_trait() == Some(trait_def_id) {
263+
G::consider_builtin_tuple_candidate(self, goal)
227264
} else {
228265
Err(NoSolution)
229266
};

compiler/rustc_trait_selection/src/solve/fulfill.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
5252
.drain(..)
5353
.map(|obligation| FulfillmentError {
5454
obligation: obligation.clone(),
55-
code: FulfillmentErrorCode::CodeSelectionError(SelectionError::Unimplemented),
55+
code: FulfillmentErrorCode::CodeAmbiguity,
5656
root_obligation: obligation,
5757
})
5858
.collect()
@@ -75,7 +75,9 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
7575
Err(NoSolution) => {
7676
errors.push(FulfillmentError {
7777
obligation: obligation.clone(),
78-
code: FulfillmentErrorCode::CodeAmbiguity,
78+
code: FulfillmentErrorCode::CodeSelectionError(
79+
SelectionError::Unimplemented,
80+
),
7981
root_obligation: obligation,
8082
});
8183
continue;

compiler/rustc_trait_selection/src/solve/project_goals.rs

+42-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::traits::{specialization_graph, translate_substs};
22

33
use super::assembly::{self, Candidate, CandidateSource};
44
use super::infcx_ext::InferCtxtExt;
5+
use super::trait_goals::structural_traits;
56
use super::{Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
67
use rustc_errors::ErrorGuaranteed;
78
use rustc_hir::def::DefKind;
@@ -11,9 +12,9 @@ use rustc_infer::traits::query::NoSolution;
1112
use rustc_infer::traits::specialization_graph::LeafDef;
1213
use rustc_infer::traits::Reveal;
1314
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
14-
use rustc_middle::ty::TypeVisitable;
1515
use rustc_middle::ty::{self, Ty, TyCtxt};
1616
use rustc_middle::ty::{ProjectionPredicate, TypeSuperVisitable, TypeVisitor};
17+
use rustc_middle::ty::{ToPredicate, TypeVisitable};
1718
use rustc_span::DUMMY_SP;
1819
use std::iter;
1920
use std::ops::ControlFlow;
@@ -351,6 +352,46 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
351352
) -> QueryResult<'tcx> {
352353
bug!("`Copy`/`Clone` does not have an associated type: {:?}", goal);
353354
}
355+
356+
fn consider_builtin_pointer_sized_candidate(
357+
_ecx: &mut EvalCtxt<'_, 'tcx>,
358+
goal: Goal<'tcx, Self>,
359+
) -> QueryResult<'tcx> {
360+
bug!("`PointerSized` does not have an associated type: {:?}", goal);
361+
}
362+
363+
fn consider_builtin_fn_trait_candidates(
364+
ecx: &mut EvalCtxt<'_, 'tcx>,
365+
goal: Goal<'tcx, Self>,
366+
goal_kind: ty::ClosureKind,
367+
) -> QueryResult<'tcx> {
368+
if let Some(tupled_inputs_and_output) =
369+
structural_traits::extract_tupled_inputs_and_output_from_callable(
370+
ecx.tcx(),
371+
goal.predicate.self_ty(),
372+
goal_kind,
373+
)?
374+
{
375+
let pred = tupled_inputs_and_output
376+
.map_bound(|(inputs, output)| ty::ProjectionPredicate {
377+
projection_ty: ecx
378+
.tcx()
379+
.mk_alias_ty(goal.predicate.def_id(), [goal.predicate.self_ty(), inputs]),
380+
term: output.into(),
381+
})
382+
.to_predicate(ecx.tcx());
383+
Self::consider_assumption(ecx, goal, pred)
384+
} else {
385+
ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
386+
}
387+
}
388+
389+
fn consider_builtin_tuple_candidate(
390+
_ecx: &mut EvalCtxt<'_, 'tcx>,
391+
goal: Goal<'tcx, Self>,
392+
) -> QueryResult<'tcx> {
393+
bug!("`Tuple` does not have an associated type: {:?}", goal);
394+
}
354395
}
355396

356397
/// This behavior is also implemented in `rustc_ty_utils` and in the old `project` code.

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+62-4
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,16 @@ use std::iter;
44

55
use super::assembly::{self, Candidate, CandidateSource};
66
use super::infcx_ext::InferCtxtExt;
7-
use super::{EvalCtxt, Goal, QueryResult};
7+
use super::{Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
88
use rustc_hir::def_id::DefId;
99
use rustc_infer::infer::InferCtxt;
1010
use rustc_infer::traits::query::NoSolution;
1111
use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
12-
use rustc_middle::ty::TraitPredicate;
13-
use rustc_middle::ty::{self, Ty, TyCtxt};
12+
use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt};
13+
use rustc_middle::ty::{TraitPredicate, TypeVisitable};
1414
use rustc_span::DUMMY_SP;
1515

16-
mod structural_traits;
16+
pub mod structural_traits;
1717

1818
impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
1919
fn self_ty(self) -> Ty<'tcx> {
@@ -127,6 +127,64 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
127127
structural_traits::instantiate_constituent_tys_for_copy_clone_trait,
128128
)
129129
}
130+
131+
fn consider_builtin_pointer_sized_candidate(
132+
ecx: &mut EvalCtxt<'_, 'tcx>,
133+
goal: Goal<'tcx, Self>,
134+
) -> QueryResult<'tcx> {
135+
if goal.predicate.self_ty().has_non_region_infer() {
136+
return ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity));
137+
}
138+
139+
let tcx = ecx.tcx();
140+
let self_ty = tcx.erase_regions(goal.predicate.self_ty());
141+
142+
if let Ok(layout) = tcx.layout_of(goal.param_env.and(self_ty))
143+
&& let usize_layout = tcx.layout_of(ty::ParamEnv::empty().and(tcx.types.usize)).unwrap().layout
144+
&& layout.layout.size() == usize_layout.size()
145+
&& layout.layout.align().abi == usize_layout.align().abi
146+
{
147+
// FIXME: We could make this faster by making a no-constraints response
148+
ecx.make_canonical_response(Certainty::Yes)
149+
} else {
150+
Err(NoSolution)
151+
}
152+
}
153+
154+
fn consider_builtin_fn_trait_candidates(
155+
ecx: &mut EvalCtxt<'_, 'tcx>,
156+
goal: Goal<'tcx, Self>,
157+
goal_kind: ty::ClosureKind,
158+
) -> QueryResult<'tcx> {
159+
if let Some(tupled_inputs_and_output) =
160+
structural_traits::extract_tupled_inputs_and_output_from_callable(
161+
ecx.tcx(),
162+
goal.predicate.self_ty(),
163+
goal_kind,
164+
)?
165+
{
166+
let pred = tupled_inputs_and_output
167+
.map_bound(|(inputs, _)| {
168+
ecx.tcx()
169+
.mk_trait_ref(goal.predicate.def_id(), [goal.predicate.self_ty(), inputs])
170+
})
171+
.to_predicate(ecx.tcx());
172+
Self::consider_assumption(ecx, goal, pred)
173+
} else {
174+
ecx.make_canonical_response(Certainty::Maybe(MaybeCause::Ambiguity))
175+
}
176+
}
177+
178+
fn consider_builtin_tuple_candidate(
179+
ecx: &mut EvalCtxt<'_, 'tcx>,
180+
goal: Goal<'tcx, Self>,
181+
) -> QueryResult<'tcx> {
182+
if let ty::Tuple(..) = goal.predicate.self_ty().kind() {
183+
ecx.make_canonical_response(Certainty::Yes)
184+
} else {
185+
Err(NoSolution)
186+
}
187+
}
130188
}
131189

132190
impl<'tcx> EvalCtxt<'_, 'tcx> {

0 commit comments

Comments
 (0)