Skip to content

Commit 7c68135

Browse files
Auto merge of #143309 - compiler-errors:param-sized-fast-path, r=<try>
[perf] Consider param-env for fast path
2 parents 085c247 + 089656e commit 7c68135

File tree

8 files changed

+57
-29
lines changed

8 files changed

+57
-29
lines changed

compiler/rustc_trait_selection/src/solve/delegate.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ use rustc_infer::traits::solve::Goal;
1212
use rustc_middle::traits::query::NoSolution;
1313
use rustc_middle::traits::solve::Certainty;
1414
use rustc_middle::ty::{
15-
self, SizedTraitKind, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
15+
self, Ty, TyCtxt, TypeFlags, TypeFoldable, TypeVisitableExt as _, TypingMode,
1616
};
1717
use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span};
1818

19-
use crate::traits::{EvaluateConstErr, ObligationCause, specialization_graph};
19+
use crate::traits::{EvaluateConstErr, ObligationCause, sizedness_fast_path, specialization_graph};
2020

2121
#[repr(transparent)]
2222
pub struct SolverDelegate<'tcx>(InferCtxt<'tcx>);
@@ -76,19 +76,11 @@ impl<'tcx> rustc_next_trait_solver::delegate::SolverDelegate for SolverDelegate<
7676

7777
if trait_pred.polarity() == ty::PredicatePolarity::Positive {
7878
match self.0.tcx.as_lang_item(trait_pred.def_id()) {
79-
Some(LangItem::Sized)
80-
if self
81-
.resolve_vars_if_possible(trait_pred.self_ty().skip_binder())
82-
.has_trivial_sizedness(self.0.tcx, SizedTraitKind::Sized) =>
83-
{
84-
return Some(Certainty::Yes);
85-
}
86-
Some(LangItem::MetaSized)
87-
if self
88-
.resolve_vars_if_possible(trait_pred.self_ty().skip_binder())
89-
.has_trivial_sizedness(self.0.tcx, SizedTraitKind::MetaSized) =>
90-
{
91-
return Some(Certainty::Yes);
79+
Some(LangItem::Sized) | Some(LangItem::MetaSized) => {
80+
let predicate = self.resolve_vars_if_possible(goal.predicate);
81+
if sizedness_fast_path(self.tcx, predicate, goal.param_env) {
82+
return Some(Certainty::Yes);
83+
}
9284
}
9385
Some(LangItem::Copy | LangItem::Clone) => {
9486
let self_ty =

compiler/rustc_trait_selection/src/traits/fulfill.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
335335

336336
let infcx = self.selcx.infcx;
337337

338-
if sizedness_fast_path(infcx.tcx, obligation.predicate) {
338+
if sizedness_fast_path(infcx.tcx, obligation.predicate, obligation.param_env) {
339339
return ProcessResult::Changed(thin_vec![]);
340340
}
341341

compiler/rustc_trait_selection/src/traits/query/type_op/prove_predicate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
1515
tcx: TyCtxt<'tcx>,
1616
key: &ParamEnvAnd<'tcx, Self>,
1717
) -> Option<Self::QueryResponse> {
18-
if sizedness_fast_path(tcx, key.value.predicate) {
18+
if sizedness_fast_path(tcx, key.value.predicate, key.param_env) {
1919
return Some(());
2020
}
2121

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
608608
None => self.check_recursion_limit(&obligation, &obligation)?,
609609
}
610610

611-
if sizedness_fast_path(self.tcx(), obligation.predicate) {
611+
if sizedness_fast_path(self.tcx(), obligation.predicate, obligation.param_env) {
612612
return Ok(EvaluatedToOk);
613613
}
614614

compiler/rustc_trait_selection/src/traits/util.rs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,23 +364,42 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for PlaceholderReplacer<'_, 'tcx> {
364364
}
365365
}
366366

367-
pub fn sizedness_fast_path<'tcx>(tcx: TyCtxt<'tcx>, predicate: ty::Predicate<'tcx>) -> bool {
367+
pub fn sizedness_fast_path<'tcx>(
368+
tcx: TyCtxt<'tcx>,
369+
predicate: ty::Predicate<'tcx>,
370+
param_env: ty::ParamEnv<'tcx>,
371+
) -> bool {
368372
// Proving `Sized`/`MetaSized`, very often on "obviously sized" types like
369373
// `&T`, accounts for about 60% percentage of the predicates we have to prove. No need to
370374
// canonicalize and all that for such cases.
371-
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_ref)) =
375+
if let ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)) =
372376
predicate.kind().skip_binder()
377+
&& trait_pred.polarity == ty::PredicatePolarity::Positive
373378
{
374-
let sizedness = match tcx.as_lang_item(trait_ref.def_id()) {
379+
let sizedness = match tcx.as_lang_item(trait_pred.def_id()) {
375380
Some(LangItem::Sized) => SizedTraitKind::Sized,
376381
Some(LangItem::MetaSized) => SizedTraitKind::MetaSized,
377382
_ => return false,
378383
};
379384

380-
if trait_ref.self_ty().has_trivial_sizedness(tcx, sizedness) {
385+
if trait_pred.self_ty().has_trivial_sizedness(tcx, sizedness) {
381386
debug!("fast path -- trivial sizedness");
382387
return true;
383388
}
389+
390+
if matches!(trait_pred.self_ty().kind(), ty::Param(_) | ty::Placeholder(_)) {
391+
for clause in param_env.caller_bounds() {
392+
if let ty::ClauseKind::Trait(clause_pred) = clause.kind().skip_binder()
393+
&& clause_pred.polarity == ty::PredicatePolarity::Positive
394+
&& clause_pred.self_ty() == trait_pred.self_ty()
395+
&& (clause_pred.def_id() == trait_pred.def_id()
396+
|| (sizedness == SizedTraitKind::MetaSized
397+
&& tcx.is_lang_item(clause_pred.def_id(), LangItem::Sized)))
398+
{
399+
return true;
400+
}
401+
}
402+
}
384403
}
385404

386405
false

compiler/rustc_traits/src/codegen.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub(crate) fn codegen_select_candidate<'tcx>(
3434
let (infcx, param_env) = tcx.infer_ctxt().ignoring_regions().build_with_typing_env(typing_env);
3535
let mut selcx = SelectionContext::new(&infcx);
3636

37-
if sizedness_fast_path(tcx, trait_ref.upcast(tcx)) {
37+
if sizedness_fast_path(tcx, trait_ref.upcast(tcx), key.typing_env.param_env) {
3838
return Ok(&*tcx.arena.alloc(ImplSource::Builtin(
3939
ty::solve::BuiltinImplSource::Trivial,
4040
Default::default(),

compiler/rustc_traits/src/evaluate_obligation.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ fn evaluate_obligation<'tcx>(
2424
debug!("evaluate_obligation: goal={:#?}", goal);
2525
let ParamEnvAnd { param_env, value: predicate } = goal;
2626

27-
if sizedness_fast_path(tcx, predicate) {
27+
if sizedness_fast_path(tcx, predicate, param_env) {
2828
return Ok(EvaluationResult::EvaluatedToOk);
2929
}
3030

tests/ui/where-clauses/ignore-err-clauses.stderr

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,30 @@ error[E0412]: cannot find type `UUU` in this scope
44
LL | UUU: Copy,
55
| ^^^ not found in this scope
66

7-
error[E0282]: type annotations needed
8-
--> $DIR/ignore-err-clauses.rs:3:14
7+
error[E0382]: use of moved value: `x`
8+
--> $DIR/ignore-err-clauses.rs:10:9
99
|
1010
LL | fn dbl<T>(x: T) -> <T as Add>::Output
11-
| ^ cannot infer type for type parameter `T`
11+
| - move occurs because `x` has type `T`, which does not implement the `Copy` trait
12+
...
13+
LL | x + x
14+
| ----^
15+
| | |
16+
| | value used here after move
17+
| `x` moved due to usage in operator
18+
|
19+
help: if `T` implemented `Clone`, you could clone the value
20+
--> $DIR/ignore-err-clauses.rs:3:8
21+
|
22+
LL | fn dbl<T>(x: T) -> <T as Add>::Output
23+
| ^ consider constraining this type parameter with `Clone`
24+
...
25+
LL | x + x
26+
| - you could clone this value
27+
note: calling this operator moves the left-hand side
28+
--> $SRC_DIR/core/src/ops/arith.rs:LL:COL
1229

1330
error: aborting due to 2 previous errors
1431

15-
Some errors have detailed explanations: E0282, E0412.
16-
For more information about an error, try `rustc --explain E0282`.
32+
Some errors have detailed explanations: E0382, E0412.
33+
For more information about an error, try `rustc --explain E0382`.

0 commit comments

Comments
 (0)