Skip to content

Commit

Permalink
Rollup merge of rust-lang#123302 - compiler-errors:sized-bound-first,…
Browse files Browse the repository at this point in the history
… r=estebank

Make sure to insert `Sized` bound first into clauses list

rust-lang#120323 made it so that we don't insert an implicit `Sized` bound whenever we see an *explicit* `Sized` bound. However, since the code that inserts implicit sized bounds puts the bound as the *first* in the list, that means that it had the **side-effect** of possibly meaning we check `Sized` *after* checking other trait bounds.

If those trait bounds result in ambiguity or overflow or something, it may change how we winnow candidates. (**edit: SEE** rust-lang#123303) This is likely the cause for the regression in rust-lang#123279 (comment), since the impl...

```rust
impl<T: Job + Sized> AsJob for T { // <----- changing this to `Sized + Job` or just `Job` (which turns into `Sized + Job`) will FIX the issue.
}
```

...looks incredibly suspicious.

Fixes [after beta-backport] rust-lang#123279.

Alternative is to revert rust-lang#120323. I don't have a strong opinion about this, but think it may be nice to keep the diagnostic changes around.
  • Loading branch information
matthiaskrgr authored Apr 2, 2024
2 parents e256d0b + f2fd2d8 commit 843a367
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
10 changes: 8 additions & 2 deletions compiler/rustc_hir_analysis/src/bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,20 @@ impl<'tcx> Bounds<'tcx> {
span: Span,
polarity: ty::PredicatePolarity,
) {
self.clauses.push((
let clause = (
trait_ref
.map_bound(|trait_ref| {
ty::ClauseKind::Trait(ty::TraitPredicate { trait_ref, polarity })
})
.to_predicate(tcx),
span,
));
);
// FIXME(-Znext-solver): We can likely remove this hack once the new trait solver lands.
if tcx.lang_items().sized_trait() == Some(trait_ref.def_id()) {
self.clauses.insert(0, clause);
} else {
self.clauses.push(clause);
}
}

pub fn push_projection_bound(
Expand Down
2 changes: 1 addition & 1 deletion tests/incremental/hashes/function_interfaces.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ pub fn second_trait_bound<T: Eq + Clone>() {}
pub fn second_builtin_bound<T: Send >() {}

#[cfg(not(any(cfail1,cfail4)))]
#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes, predicates_of")]
#[rustc_clean(cfg = "cfail2", except = "opt_hir_owner_nodes")]
#[rustc_clean(cfg = "cfail3")]
#[rustc_clean(cfg = "cfail5", except = "opt_hir_owner_nodes, predicates_of")]
#[rustc_clean(cfg = "cfail6")]
Expand Down
30 changes: 30 additions & 0 deletions tests/ui/methods/probe-overflow-due-to-sized-predicate-ordering.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//@ check-pass
// Regression test due to #123279

pub trait Job: AsJob {
fn run_once(&self);
}

impl<F: Fn()> Job for F {
fn run_once(&self) {
todo!()
}
}

pub trait AsJob {}

// Ensure that `T: Sized + Job` by reordering the explicit `Sized` to where
// the implicit sized pred would go.
impl<T: Job + Sized> AsJob for T {}

pub struct LoopingJobService {
job: Box<dyn Job>,
}

impl Job for LoopingJobService {
fn run_once(&self) {
self.job.run_once()
}
}

fn main() {}

0 comments on commit 843a367

Please sign in to comment.