Skip to content

Commit 51b1964

Browse files
committed
Auto merge of rust-lang#138176 - compiler-errors:rigid-sized-obl, r=<try>
Prefer built-in sized obligations for rigid types always r? lcnr
2 parents 03eb454 + 49e4fbc commit 51b1964

File tree

4 files changed

+41
-6
lines changed

4 files changed

+41
-6
lines changed

compiler/rustc_middle/src/traits/select.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,13 @@ pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>),
9595
/// parameter environment.
9696
#[derive(PartialEq, Eq, Debug, Clone, TypeVisitable)]
9797
pub enum SelectionCandidate<'tcx> {
98+
/// UwU
99+
SizedCandidate,
100+
98101
/// A builtin implementation for some specific traits, used in cases
99102
/// where we cannot rely an ordinary library implementations.
100103
///
101-
/// The most notable examples are `sized`, `Copy` and `Clone`. This is also
104+
/// The most notable examples are `Copy` and `Clone`. This is also
102105
/// used for the `DiscriminantKind` and `Pointee` trait, both of which have
103106
/// an associated type.
104107
BuiltinCandidate {

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
8686
// `Pointee` is automatically implemented for every type.
8787
candidates.vec.push(BuiltinCandidate { has_nested: false });
8888
} else if tcx.is_lang_item(def_id, LangItem::Sized) {
89-
// Sized is never implementable by end-users, it is
90-
// always automatically computed.
91-
let sized_conditions = self.sized_conditions(obligation);
92-
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
89+
self.assemble_builtin_sized_candidate(obligation, &mut candidates);
9390
} else if tcx.is_lang_item(def_id, LangItem::Unsize) {
9491
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
9592
} else if tcx.is_lang_item(def_id, LangItem::Destruct) {
@@ -1059,6 +1056,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
10591056
/// Assembles the trait which are built-in to the language itself:
10601057
/// `Copy`, `Clone` and `Sized`.
10611058
#[instrument(level = "debug", skip(self, candidates))]
1059+
fn assemble_builtin_sized_candidate(
1060+
&mut self,
1061+
obligation: &PolyTraitObligation<'tcx>,
1062+
candidates: &mut SelectionCandidateSet<'tcx>,
1063+
) {
1064+
match self.sized_conditions(obligation) {
1065+
BuiltinImplConditions::Where(_) => {
1066+
candidates.vec.push(SizedCandidate);
1067+
}
1068+
BuiltinImplConditions::None => {}
1069+
BuiltinImplConditions::Ambiguous => {
1070+
candidates.ambiguous = true;
1071+
}
1072+
}
1073+
}
1074+
1075+
/// Assembles the trait which are built-in to the language itself:
1076+
/// e.g. `Copy` and `Clone`.
1077+
#[instrument(level = "debug", skip(self, candidates))]
10621078
fn assemble_builtin_bound_candidates(
10631079
&mut self,
10641080
conditions: BuiltinImplConditions<'tcx>,

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+5
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
4040
candidate: SelectionCandidate<'tcx>,
4141
) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
4242
let mut impl_src = match candidate {
43+
SizedCandidate => {
44+
let data = self.confirm_builtin_candidate(obligation, true);
45+
ImplSource::Builtin(BuiltinImplSource::Misc, data)
46+
}
47+
4348
BuiltinCandidate { has_nested } => {
4449
let data = self.confirm_builtin_candidate(obligation, has_nested);
4550
ImplSource::Builtin(BuiltinImplSource::Misc, data)

compiler/rustc_trait_selection/src/traits/select/mod.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -1801,6 +1801,16 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
18011801
return Some(candidates.pop().unwrap().candidate);
18021802
}
18031803

1804+
// We prefer `Sized` candidates over everything.
1805+
let mut sized_candidates =
1806+
candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate));
1807+
if let Some(_sized_candidate) = sized_candidates.next() {
1808+
// There should only ever be a single sized candidate
1809+
// as they would otherwise overlap.
1810+
debug_assert_eq!(sized_candidates.next(), None);
1811+
return Some(SizedCandidate);
1812+
}
1813+
18041814
// We prefer trivial builtin candidates, i.e. builtin impls without any nested
18051815
// requirements, over all others. This is a fix for #53123 and prevents winnowing
18061816
// from accidentally extending the lifetime of a variable.
@@ -1940,7 +1950,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
19401950
// Don't use impl candidates which overlap with other candidates.
19411951
// This should pretty much only ever happen with malformed impls.
19421952
if candidates.iter().all(|c| match c.candidate {
1943-
BuiltinCandidate { has_nested: _ }
1953+
SizedCandidate
1954+
| BuiltinCandidate { has_nested: _ }
19441955
| TransmutabilityCandidate
19451956
| AutoImplCandidate
19461957
| ClosureCandidate { .. }

0 commit comments

Comments
 (0)