Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion compiler/rustc_data_structures/src/profiling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ const EVENT_FILTERS_BY_NAME: &[(&str, EventFilter)] = &[
("generic-activity", EventFilter::GENERIC_ACTIVITIES),
("query-provider", EventFilter::QUERY_PROVIDERS),
("query-cache-hit", EventFilter::QUERY_CACHE_HITS),
("query-cache-hit-count", EventFilter::QUERY_CACHE_HITS),
("query-cache-hit-count", EventFilter::QUERY_CACHE_HIT_COUNTS),
("query-blocked", EventFilter::QUERY_BLOCKED),
("incr-cache-load", EventFilter::INCR_CACHE_LOADS),
("query-keys", EventFilter::QUERY_KEYS),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,9 +184,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
return true;
}

for param in [param_to_point_at, fallback_param_to_point_at, self_param_to_point_at]
.into_iter()
.flatten()
for param in [
predicate_self_type_to_point_at,
param_to_point_at,
fallback_param_to_point_at,
self_param_to_point_at,
]
.into_iter()
.flatten()
{
if self.blame_specific_arg_if_possible(
error,
Expand Down
9 changes: 2 additions & 7 deletions compiler/rustc_middle/src/traits/select.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,15 @@ pub type EvaluationCache<'tcx, ENV> = Cache<(ENV, ty::PolyTraitPredicate<'tcx>),
pub enum SelectionCandidate<'tcx> {
/// A built-in implementation for the `Sized` trait. This is preferred
/// over all other candidates.
SizedCandidate {
has_nested: bool,
},
SizedCandidate,

/// A builtin implementation for some specific traits, used in cases
/// where we cannot rely an ordinary library implementations.
///
/// The most notable examples are `Copy` and `Clone`. This is also
/// used for the `DiscriminantKind` and `Pointee` trait, both of which have
/// an associated type.
BuiltinCandidate {
/// `false` if there are no *further* obligations.
has_nested: bool,
},
BuiltinCandidate,

/// Implementation of transmutability trait.
TransmutabilityCandidate,
Expand Down
6 changes: 4 additions & 2 deletions compiler/rustc_parse/src/parser/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1293,8 +1293,10 @@ impl<'a> Parser<'a> {
let kind = if pat {
let guar = self
.dcx()
.struct_span_err(blk_span, "`inline_const_pat` has been removed")
.with_help("use a named `const`-item or an `if`-guard instead")
.struct_span_err(blk_span, "const blocks cannot be used as patterns")
.with_help(
"use a named `const`-item or an `if`-guard (`x if x == const { ... }`) instead",
)
.emit();
ExprKind::Err(guar)
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
Some(LangItem::DiscriminantKind) => {
// `DiscriminantKind` is automatically implemented for every type.
candidates.vec.push(BuiltinCandidate { has_nested: false });
candidates.vec.push(BuiltinCandidate);
}
Some(LangItem::PointeeTrait) => {
// `Pointee` is automatically implemented for every type.
candidates.vec.push(BuiltinCandidate { has_nested: false });
candidates.vec.push(BuiltinCandidate);
}
Some(LangItem::Sized) => {
self.assemble_builtin_sized_candidate(
Expand Down Expand Up @@ -365,7 +365,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
{
debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",);

candidates.vec.push(BuiltinCandidate { has_nested: false });
candidates.vec.push(BuiltinCandidate);
}
}

Expand Down Expand Up @@ -810,7 +810,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
hir::Movability::Movable => {
// Movable coroutines are always `Unpin`, so add an
// unconditional builtin candidate.
candidates.vec.push(BuiltinCandidate { has_nested: false });
candidates.vec.push(BuiltinCandidate);
}
}
}
Expand Down Expand Up @@ -1122,10 +1122,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
sizedness: SizedTraitKind,
) {
match self.sizedness_conditions(obligation, sizedness) {
BuiltinImplConditions::Where(nested) => {
candidates
.vec
.push(SizedCandidate { has_nested: !nested.skip_binder().is_empty() });
BuiltinImplConditions::Where(_nested) => {
candidates.vec.push(SizedCandidate);
}
BuiltinImplConditions::None => {}
BuiltinImplConditions::Ambiguous => {
Expand All @@ -1143,10 +1141,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates: &mut SelectionCandidateSet<'tcx>,
) {
match conditions {
BuiltinImplConditions::Where(nested) => {
candidates
.vec
.push(BuiltinCandidate { has_nested: !nested.skip_binder().is_empty() });
BuiltinImplConditions::Where(_) => {
candidates.vec.push(BuiltinCandidate);
}
BuiltinImplConditions::None => {}
BuiltinImplConditions::Ambiguous => {
Expand All @@ -1160,7 +1156,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
_obligation: &PolyTraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) {
candidates.vec.push(BuiltinCandidate { has_nested: false });
candidates.vec.push(BuiltinCandidate);
}

fn assemble_candidate_for_tuple(
Expand All @@ -1171,7 +1167,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
match self_ty.kind() {
ty::Tuple(_) => {
candidates.vec.push(BuiltinCandidate { has_nested: false });
candidates.vec.push(BuiltinCandidate);
}
ty::Infer(ty::TyVar(_)) => {
candidates.ambiguous = true;
Expand Down Expand Up @@ -1215,7 +1211,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let self_ty = self.infcx.resolve_vars_if_possible(obligation.self_ty());

match self_ty.skip_binder().kind() {
ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate { has_nested: false }),
ty::FnPtr(..) => candidates.vec.push(BuiltinCandidate),
ty::Bool
| ty::Char
| ty::Int(_)
Expand Down
79 changes: 38 additions & 41 deletions compiler/rustc_trait_selection/src/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidate: SelectionCandidate<'tcx>,
) -> Result<Selection<'tcx>, SelectionError<'tcx>> {
Ok(match candidate {
SizedCandidate { has_nested } => {
let data = self.confirm_builtin_candidate(obligation, has_nested);
SizedCandidate => {
let data = self.confirm_builtin_candidate(obligation);
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}

BuiltinCandidate { has_nested } => {
let data = self.confirm_builtin_candidate(obligation, has_nested);
BuiltinCandidate => {
let data = self.confirm_builtin_candidate(obligation);
ImplSource::Builtin(BuiltinImplSource::Misc, data)
}

Expand Down Expand Up @@ -249,50 +249,47 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}

#[instrument(level = "debug", skip(self), ret)]
fn confirm_builtin_candidate(
&mut self,
obligation: &PolyTraitObligation<'tcx>,
has_nested: bool,
) -> PredicateObligations<'tcx> {
debug!(?obligation, ?has_nested, "confirm_builtin_candidate");

debug!(?obligation, "confirm_builtin_candidate");
let tcx = self.tcx();
let obligations = if has_nested {
let trait_def = obligation.predicate.def_id();
let conditions = match tcx.as_lang_item(trait_def) {
Some(LangItem::Sized) => {
self.sizedness_conditions(obligation, SizedTraitKind::Sized)
}
Some(LangItem::MetaSized) => {
self.sizedness_conditions(obligation, SizedTraitKind::MetaSized)
}
Some(LangItem::PointeeSized) => {
bug!("`PointeeSized` is removing during lowering");
}
Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
};
let BuiltinImplConditions::Where(types) = conditions else {
bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
};
let types = self.infcx.enter_forall_and_leak_universe(types);

let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
self.collect_predicates_for_types(
obligation.param_env,
cause,
obligation.recursion_depth + 1,
trait_def,
types,
)
} else {
PredicateObligations::new()
let trait_def = obligation.predicate.def_id();
let conditions = match tcx.as_lang_item(trait_def) {
Some(LangItem::Sized) => self.sizedness_conditions(obligation, SizedTraitKind::Sized),
Some(LangItem::MetaSized) => {
self.sizedness_conditions(obligation, SizedTraitKind::MetaSized)
}
Some(LangItem::PointeeSized) => {
bug!("`PointeeSized` is removing during lowering");
}
Some(LangItem::Copy | LangItem::Clone) => self.copy_clone_conditions(obligation),
Some(LangItem::FusedIterator) => self.fused_iterator_conditions(obligation),
Some(
LangItem::Destruct
| LangItem::DiscriminantKind
| LangItem::FnPtrTrait
| LangItem::PointeeTrait
| LangItem::Tuple
| LangItem::Unpin,
) => BuiltinImplConditions::Where(ty::Binder::dummy(vec![])),
other => bug!("unexpected builtin trait {trait_def:?} ({other:?})"),
};
let BuiltinImplConditions::Where(types) = conditions else {
bug!("obligation {:?} had matched a builtin impl but now doesn't", obligation);
};
let types = self.infcx.enter_forall_and_leak_universe(types);

debug!(?obligations);

obligations
let cause = obligation.derived_cause(ObligationCauseCode::BuiltinDerived);
self.collect_predicates_for_types(
obligation.param_env,
cause,
obligation.recursion_depth + 1,
trait_def,
types,
)
}

#[instrument(level = "debug", skip(self))]
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_trait_selection/src/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1834,7 +1834,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {

// We prefer `Sized` candidates over everything.
let mut sized_candidates =
candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate { has_nested: _ }));
candidates.iter().filter(|c| matches!(c.candidate, SizedCandidate));
if let Some(sized_candidate) = sized_candidates.next() {
// There should only ever be a single sized candidate
// as they would otherwise overlap.
Expand Down Expand Up @@ -1986,8 +1986,8 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
// Don't use impl candidates which overlap with other candidates.
// This should pretty much only ever happen with malformed impls.
if candidates.iter().all(|c| match c.candidate {
SizedCandidate { has_nested: _ }
| BuiltinCandidate { has_nested: _ }
SizedCandidate
| BuiltinCandidate
| TransmutabilityCandidate
| AutoImplCandidate
| ClosureCandidate { .. }
Expand Down
34 changes: 24 additions & 10 deletions compiler/rustc_ty_utils/src/assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,17 @@ impl<'tcx> Visitor<'tcx> for RPITVisitor<'tcx> {
}
}

struct DisambiguatorIdxVisitor {
depth: u32,
}

impl<'tcx> Visitor<'tcx> for DisambiguatorIdxVisitor {
fn visit_opaque_ty(&mut self, opaque: &'tcx hir::OpaqueTy<'tcx>) -> Self::Result {
self.depth += 1;
intravisit::walk_opaque_ty(self, opaque)
}
}

/// Given an `fn_def_id` of a trait or a trait implementation:
///
/// if `fn_def_id` is a function defined inside a trait, then it synthesizes
Expand Down Expand Up @@ -211,16 +222,19 @@ fn associated_types_for_impl_traits_in_associated_fn(
let disambiguator_idx = trait_item_refs
.iter()
.take_while(|item| item.id.owner_id.def_id != fn_def_id)
.fold(0, |acc, item| {
if !matches!(item.kind, hir::AssocItemKind::Fn { .. }) {
acc
} else if def_path_id(item.id.owner_id.def_id) == def_path_data {
tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator
+ 1
} else {
acc
}
});
.filter(|item| {
matches!(item.kind, hir::AssocItemKind::Fn { .. })
&& def_path_id(item.id.owner_id.def_id) == def_path_data
})
.last()
.map(|item| {
let output = tcx.hir_get_fn_output(item.id.owner_id.def_id).unwrap();
let mut visitor = DisambiguatorIdxVisitor { depth: 0 };
visitor.visit_fn_ret_ty(output);
tcx.def_key(item.id.owner_id.def_id).disambiguated_data.disambiguator
+ visitor.depth
})
.unwrap_or_default();

let data = DefPathData::AnonAssocTy(def_path_data);
let mut visitor = RPITVisitor {
Expand Down
8 changes: 5 additions & 3 deletions library/alloc/src/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ use crate::vec::{self, Vec};
/// ```
///
/// Next, what should `s[i]` return? Because indexing returns a reference
/// to underlying data it could be `&u8`, `&[u8]`, or something else similar.
/// to underlying data it could be `&u8`, `&[u8]`, or something similar.
/// Since we're only providing one index, `&u8` makes the most sense but that
/// might not be what the user expects and can be explicitly achieved with
/// [`as_bytes()`]:
Expand Down Expand Up @@ -2875,7 +2875,8 @@ macro_rules! impl_to_string {
out = String::with_capacity(SIZE);
}

out.push_str(self.unsigned_abs()._fmt(&mut buf));
// SAFETY: `buf` is always big enough to contain all the digits.
unsafe { out.push_str(self.unsigned_abs()._fmt(&mut buf)); }
out
}
}
Expand All @@ -2887,7 +2888,8 @@ macro_rules! impl_to_string {
const SIZE: usize = $unsigned::MAX.ilog10() as usize + 1;
let mut buf = [core::mem::MaybeUninit::<u8>::uninit(); SIZE];

self._fmt(&mut buf).to_string()
// SAFETY: `buf` is always big enough to contain all the digits.
unsafe { self._fmt(&mut buf).to_string() }
}
}
)*
Expand Down
1 change: 1 addition & 0 deletions library/alloctests/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#![feature(downcast_unchecked)]
#![feature(exact_size_is_empty)]
#![feature(hashmap_internals)]
#![feature(int_format_into)]
#![feature(linked_list_cursors)]
#![feature(map_try_insert)]
#![feature(pattern)]
Expand Down
Loading
Loading