Skip to content

Commit 96dfdf7

Browse files
committed
Allow trivial bounds on impls
1 parent c5f02dc commit 96dfdf7

4 files changed

Lines changed: 23 additions & 14 deletions

File tree

‎compiler/rustc_middle/src/ty/generics.rs‎

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -426,14 +426,15 @@ impl<'tcx> GenericPredicates<'tcx> {
426426
type Result = ControlFlow<()>;
427427
fn visit_region(&mut self, r: Region<'tcx>) -> Self::Result {
428428
match r.kind() {
429-
RegionKind::ReEarlyParam(_param) => ControlFlow::Break(()),
430-
RegionKind::ReBound(..)
431-
| RegionKind::ReLateParam(_)
429+
RegionKind::ReEarlyParam(_)
432430
| RegionKind::ReStatic
433431
| RegionKind::ReVar(_)
434432
| RegionKind::RePlaceholder(_)
435433
| RegionKind::ReErased
436-
| RegionKind::ReError(_) => ControlFlow::Continue(()),
434+
| RegionKind::ReError(_) => ControlFlow::Break(()),
435+
RegionKind::ReBound(..) | RegionKind::ReLateParam(_) => {
436+
ControlFlow::Continue(())
437+
}
437438
}
438439
}
439440

@@ -454,10 +455,18 @@ impl<'tcx> GenericPredicates<'tcx> {
454455
// don't allow this impl to be used.
455456
self.predicates.iter().all(|(clause, _)| {
456457
match clause.kind().skip_binder() {
457-
ClauseKind::Trait(_trait_predicate) => {
458-
// FIXME(try_as_dyn): allow trait bounds that do not mention lifetimes.
459-
// These bounds themselves are fine, as their impls either are fine or
460-
// rejected by this very check when encountered.
458+
ClauseKind::Trait(trait_predicate) => {
459+
// In a `T: Trait`, if the rhs bound does not contain any generic params
460+
// or 'static lifetimes, then it cannot transitively cause such requirements,
461+
// considering we apply the fully-generic-for-reflection rules to any impls for
462+
// that trait, too.
463+
if matches!(trait_predicate.self_ty().kind(), ty::Param(_))
464+
&& trait_predicate.trait_ref.args[1..]
465+
.iter()
466+
.all(|arg| arg.visit_with(&mut ParamChecker).is_continue())
467+
{
468+
return true;
469+
}
461470
}
462471
ClauseKind::RegionOutlives(_)
463472
| ClauseKind::TypeOutlives(_)

‎compiler/rustc_next_trait_solver/src/solve/trait_goals.rs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
33
use rustc_type_ir::data_structures::IndexSet;
44
use rustc_type_ir::fast_reject::DeepRejectCtxt;
5-
use rustc_type_ir::{ExistentialPredicate, GenericArgKind, inherent::*};
5+
use rustc_type_ir::inherent::*;
66
use rustc_type_ir::lang_items::SolverTraitLangItem;
77
use rustc_type_ir::solve::{
88
AliasBoundKind, CandidatePreferenceMode, CanonicalResponse, SizedTraitKind,
99
};
1010
use rustc_type_ir::{
11-
self as ty, Interner, Movability, PredicatePolarity, TraitPredicate, TraitRef,
12-
TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
11+
self as ty, ExistentialPredicate, GenericArgKind, Interner, Movability, PredicatePolarity,
12+
TraitPredicate, TraitRef, TypeVisitableExt as _, TypingMode, Upcast as _, elaborate,
1313
};
1414
use tracing::{debug, instrument, trace};
1515

‎library/core/src/any.rs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -910,7 +910,7 @@ pub const fn type_name_of_val<T: ?Sized>(_val: &T) -> &'static str {
910910
/// Trait that is automatically implemented for all `dyn Trait<'b, C> + 'a`
911911
/// * without assoc type bounds,
912912
/// * adds `T: 'a + 'b` requirements, and
913-
/// * `C: 'static` requirements.
913+
/// * `C: 'static` requirements on all params of the dyn trait.
914914
///
915915
/// This is required for `try_as_dyn` to be able to soundly convert non-static
916916
/// types to `dyn Trait`.

‎tests/ui/any/try_as_dyn_generic_impl.rs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ impl<T> Trait for Thing<T> {}
99

1010
const _: () = {
1111
let thing = Thing(1);
12-
assert!(try_as_dyn::<_, dyn Trait>(&thing).is_none());
12+
assert!(try_as_dyn::<_, dyn Trait>(&thing).is_some());
1313
};
1414

1515
struct Thing2<T>(T);
1616
impl<T: std::fmt::Debug> Trait for Thing2<T> {}
1717

1818
const _: () = {
1919
let thing = Thing2(1);
20-
assert!(try_as_dyn::<_, dyn Trait>(&thing).is_none());
20+
assert!(try_as_dyn::<_, dyn Trait>(&thing).is_some());
2121
};
2222

2323
trait Trait2 {}

0 commit comments

Comments
 (0)