Skip to content

Commit 8996ea9

Browse files
committed
Auto merge of rust-lang#107853 - Dylan-DPC:rollup-macf1qo, r=Dylan-DPC
Rollup of 6 pull requests Successful merges: - rust-lang#107648 (unused-lifetimes: don't warn about lifetimes originating from expanded code) - rust-lang#107655 (rustdoc: use the same URL escape rules for fragments as for examples) - rust-lang#107659 (test: snapshot for derive suggestion in diff files) - rust-lang#107786 (Implement some tweaks in the new solver) - rust-lang#107803 (Do not bring trait alias supertraits into scope) - rust-lang#107815 (Disqualify `auto trait` built-in impl in new solver if explicit `impl` exists) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents 8cca42a + b080a1a commit 8996ea9

25 files changed

+437
-265
lines changed

compiler/rustc_errors/src/emitter.rs

+11-11
Original file line numberDiff line numberDiff line change
@@ -1796,17 +1796,17 @@ impl EmitterWriter {
17961796
// telling users to make a change but not clarifying *where*.
17971797
let loc = sm.lookup_char_pos(parts[0].span.lo());
17981798
if loc.file.name != sm.span_to_filename(span) && loc.file.name.is_real() {
1799-
buffer.puts(row_num - 1, 0, "--> ", Style::LineNumber);
1800-
buffer.append(
1801-
row_num - 1,
1802-
&format!(
1803-
"{}:{}:{}",
1804-
sm.filename_for_diagnostics(&loc.file.name),
1805-
sm.doctest_offset_line(&loc.file.name, loc.line),
1806-
loc.col.0 + 1,
1807-
),
1808-
Style::LineAndColumn,
1809-
);
1799+
let arrow = "--> ";
1800+
buffer.puts(row_num - 1, 0, arrow, Style::LineNumber);
1801+
let filename = sm.filename_for_diagnostics(&loc.file.name);
1802+
let offset = sm.doctest_offset_line(&loc.file.name, loc.line);
1803+
let message = format!("{}:{}:{}", filename, offset, loc.col.0 + 1);
1804+
if row_num == 2 {
1805+
let col = usize::max(max_line_num_len + 1, arrow.len());
1806+
buffer.puts(1, col, &message, Style::LineAndColumn);
1807+
} else {
1808+
buffer.append(row_num - 1, &message, Style::LineAndColumn);
1809+
}
18101810
for _ in 0..max_line_num_len {
18111811
buffer.prepend(row_num - 1, " ", Style::NoStyle);
18121812
}

compiler/rustc_hir_typeck/src/method/probe.rs

+31-17
Original file line numberDiff line numberDiff line change
@@ -951,24 +951,38 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
951951
let trait_ref = self.tcx.mk_trait_ref(trait_def_id, trait_substs);
952952

953953
if self.tcx.is_trait_alias(trait_def_id) {
954-
// For trait aliases, assume all supertraits are relevant.
955-
let bounds = iter::once(ty::Binder::dummy(trait_ref));
956-
self.elaborate_bounds(bounds, |this, new_trait_ref, item| {
957-
let new_trait_ref = this.erase_late_bound_regions(new_trait_ref);
954+
// For trait aliases, recursively assume all explicitly named traits are relevant
955+
for expansion in traits::expand_trait_aliases(
956+
self.tcx,
957+
iter::once((ty::Binder::dummy(trait_ref), self.span)),
958+
) {
959+
let bound_trait_ref = expansion.trait_ref();
960+
for item in self.impl_or_trait_item(bound_trait_ref.def_id()) {
961+
if !self.has_applicable_self(&item) {
962+
self.record_static_candidate(CandidateSource::Trait(
963+
bound_trait_ref.def_id(),
964+
));
965+
} else {
966+
let new_trait_ref = self.erase_late_bound_regions(bound_trait_ref);
958967

959-
let (xform_self_ty, xform_ret_ty) =
960-
this.xform_self_ty(&item, new_trait_ref.self_ty(), new_trait_ref.substs);
961-
this.push_candidate(
962-
Candidate {
963-
xform_self_ty,
964-
xform_ret_ty,
965-
item,
966-
import_ids: import_ids.clone(),
967-
kind: TraitCandidate(new_trait_ref),
968-
},
969-
false,
970-
);
971-
});
968+
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(
969+
&item,
970+
new_trait_ref.self_ty(),
971+
new_trait_ref.substs,
972+
);
973+
self.push_candidate(
974+
Candidate {
975+
xform_self_ty,
976+
xform_ret_ty,
977+
item,
978+
import_ids: import_ids.clone(),
979+
kind: TraitCandidate(new_trait_ref),
980+
},
981+
false,
982+
);
983+
}
984+
}
985+
}
972986
} else {
973987
debug_assert!(self.tcx.is_trait(trait_def_id));
974988
if self.tcx.trait_is_auto(trait_def_id) {

compiler/rustc_resolve/src/late/diagnostics.rs

+16-12
Original file line numberDiff line numberDiff line change
@@ -2244,19 +2244,23 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
22442244
}
22452245
None => {
22462246
debug!(?param.ident, ?param.ident.span);
2247-
22482247
let deletion_span = deletion_span();
2249-
self.r.lint_buffer.buffer_lint_with_diagnostic(
2250-
lint::builtin::UNUSED_LIFETIMES,
2251-
param.id,
2252-
param.ident.span,
2253-
&format!("lifetime parameter `{}` never used", param.ident),
2254-
lint::BuiltinLintDiagnostics::SingleUseLifetime {
2255-
param_span: param.ident.span,
2256-
use_span: None,
2257-
deletion_span,
2258-
},
2259-
);
2248+
// the give lifetime originates from expanded code so we won't be able to remove it #104432
2249+
let lifetime_only_in_expanded_code =
2250+
deletion_span.map(|sp| sp.in_derive_expansion()).unwrap_or(true);
2251+
if !lifetime_only_in_expanded_code {
2252+
self.r.lint_buffer.buffer_lint_with_diagnostic(
2253+
lint::builtin::UNUSED_LIFETIMES,
2254+
param.id,
2255+
param.ident.span,
2256+
&format!("lifetime parameter `{}` never used", param.ident),
2257+
lint::BuiltinLintDiagnostics::SingleUseLifetime {
2258+
param_span: param.ident.span,
2259+
use_span: None,
2260+
deletion_span,
2261+
},
2262+
);
2263+
}
22602264
}
22612265
}
22622266
}

compiler/rustc_trait_selection/src/solve/assembly.rs

+76-5
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use super::infcx_ext::InferCtxtExt;
44
#[cfg(doc)]
55
use super::trait_goals::structural_traits::*;
6-
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, QueryResult};
6+
use super::{CanonicalResponse, Certainty, EvalCtxt, Goal, MaybeCause, QueryResult};
77
use rustc_hir::def_id::DefId;
88
use rustc_infer::traits::query::NoSolution;
99
use rustc_infer::traits::util::elaborate_predicates;
@@ -399,10 +399,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
399399
ty::Alias(_, alias_ty) => alias_ty,
400400
};
401401

402-
for (assumption, _) in self
403-
.tcx()
404-
.bound_explicit_item_bounds(alias_ty.def_id)
405-
.subst_iter_copied(self.tcx(), alias_ty.substs)
402+
for assumption in self.tcx().item_bounds(alias_ty.def_id).subst(self.tcx(), alias_ty.substs)
406403
{
407404
match G::consider_assumption(self, goal, assumption) {
408405
Ok(result) => {
@@ -462,4 +459,78 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
462459
}
463460
}
464461
}
462+
463+
#[instrument(level = "debug", skip(self), ret)]
464+
pub(super) fn merge_candidates_and_discard_reservation_impls(
465+
&mut self,
466+
mut candidates: Vec<Candidate<'tcx>>,
467+
) -> QueryResult<'tcx> {
468+
match candidates.len() {
469+
0 => return Err(NoSolution),
470+
1 => return Ok(self.discard_reservation_impl(candidates.pop().unwrap()).result),
471+
_ => {}
472+
}
473+
474+
if candidates.len() > 1 {
475+
let mut i = 0;
476+
'outer: while i < candidates.len() {
477+
for j in (0..candidates.len()).filter(|&j| i != j) {
478+
if self.trait_candidate_should_be_dropped_in_favor_of(
479+
&candidates[i],
480+
&candidates[j],
481+
) {
482+
debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len());
483+
candidates.swap_remove(i);
484+
continue 'outer;
485+
}
486+
}
487+
488+
debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len());
489+
i += 1;
490+
}
491+
492+
// If there are *STILL* multiple candidates, give up
493+
// and report ambiguity.
494+
if candidates.len() > 1 {
495+
let certainty = if candidates.iter().all(|x| {
496+
matches!(x.result.value.certainty, Certainty::Maybe(MaybeCause::Overflow))
497+
}) {
498+
Certainty::Maybe(MaybeCause::Overflow)
499+
} else {
500+
Certainty::AMBIGUOUS
501+
};
502+
return self.make_canonical_response(certainty);
503+
}
504+
}
505+
506+
Ok(self.discard_reservation_impl(candidates.pop().unwrap()).result)
507+
}
508+
509+
fn trait_candidate_should_be_dropped_in_favor_of(
510+
&self,
511+
candidate: &Candidate<'tcx>,
512+
other: &Candidate<'tcx>,
513+
) -> bool {
514+
// FIXME: implement this
515+
match (candidate.source, other.source) {
516+
(CandidateSource::Impl(_), _)
517+
| (CandidateSource::ParamEnv(_), _)
518+
| (CandidateSource::AliasBound, _)
519+
| (CandidateSource::BuiltinImpl, _) => false,
520+
}
521+
}
522+
523+
fn discard_reservation_impl(&self, mut candidate: Candidate<'tcx>) -> Candidate<'tcx> {
524+
if let CandidateSource::Impl(def_id) = candidate.source {
525+
if let ty::ImplPolarity::Reservation = self.tcx().impl_polarity(def_id) {
526+
debug!("Selected reservation impl");
527+
// We assemble all candidates inside of a probe so by
528+
// making a new canonical response here our result will
529+
// have no constraints.
530+
candidate.result = self.make_canonical_response(Certainty::AMBIGUOUS).unwrap();
531+
}
532+
}
533+
534+
candidate
535+
}
465536
}

compiler/rustc_trait_selection/src/solve/project_goals.rs

+4-56
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::traits::{specialization_graph, translate_substs};
22

3-
use super::assembly::{self, Candidate, CandidateSource};
3+
use super::assembly;
44
use super::infcx_ext::InferCtxtExt;
55
use super::trait_goals::structural_traits;
66
use super::{Certainty, EvalCtxt, Goal, QueryResult};
@@ -34,7 +34,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
3434
// projection cache in the solver.
3535
if self.term_is_fully_unconstrained(goal) {
3636
let candidates = self.assemble_and_evaluate_candidates(goal);
37-
self.merge_project_candidates(candidates)
37+
self.merge_candidates_and_discard_reservation_impls(candidates)
3838
} else {
3939
let predicate = goal.predicate;
4040
let unconstrained_rhs = match predicate.term.unpack() {
@@ -153,59 +153,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
153153

154154
self.make_canonical_response(normalization_certainty.unify_and(rhs_certainty))
155155
}
156-
157-
fn merge_project_candidates(
158-
&mut self,
159-
mut candidates: Vec<Candidate<'tcx>>,
160-
) -> QueryResult<'tcx> {
161-
match candidates.len() {
162-
0 => return Err(NoSolution),
163-
1 => return Ok(candidates.pop().unwrap().result),
164-
_ => {}
165-
}
166-
167-
if candidates.len() > 1 {
168-
let mut i = 0;
169-
'outer: while i < candidates.len() {
170-
for j in (0..candidates.len()).filter(|&j| i != j) {
171-
if self.project_candidate_should_be_dropped_in_favor_of(
172-
&candidates[i],
173-
&candidates[j],
174-
) {
175-
debug!(candidate = ?candidates[i], "Dropping candidate #{}/{}", i, candidates.len());
176-
candidates.swap_remove(i);
177-
continue 'outer;
178-
}
179-
}
180-
181-
debug!(candidate = ?candidates[i], "Retaining candidate #{}/{}", i, candidates.len());
182-
// If there are *STILL* multiple candidates, give up
183-
// and report ambiguity.
184-
i += 1;
185-
if i > 1 {
186-
debug!("multiple matches, ambig");
187-
// FIXME: return overflow if all candidates overflow, otherwise return ambiguity.
188-
unimplemented!();
189-
}
190-
}
191-
}
192-
193-
Ok(candidates.pop().unwrap().result)
194-
}
195-
196-
fn project_candidate_should_be_dropped_in_favor_of(
197-
&self,
198-
candidate: &Candidate<'tcx>,
199-
other: &Candidate<'tcx>,
200-
) -> bool {
201-
// FIXME: implement this
202-
match (candidate.source, other.source) {
203-
(CandidateSource::Impl(_), _)
204-
| (CandidateSource::ParamEnv(_), _)
205-
| (CandidateSource::BuiltinImpl, _)
206-
| (CandidateSource::AliasBound, _) => unimplemented!(),
207-
}
208-
}
209156
}
210157

211158
impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
@@ -452,7 +399,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
452399
[ty::GenericArg::from(goal.predicate.self_ty())],
453400
));
454401

455-
let is_sized_certainty = ecx.evaluate_goal(goal.with(tcx, sized_predicate))?.1;
402+
let (_, is_sized_certainty) =
403+
ecx.evaluate_goal(goal.with(tcx, sized_predicate))?;
456404
return ecx.eq_term_and_make_canonical_response(
457405
goal,
458406
is_sized_certainty,

0 commit comments

Comments
 (0)