Skip to content

Commit 29f1dba

Browse files
committed
Remove 'static requirement on try_as_dyn
1 parent 58b270b commit 29f1dba

File tree

27 files changed

+182
-17
lines changed

27 files changed

+182
-17
lines changed

compiler/rustc_const_eval/src/interpret/intrinsics.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
236236
};
237237

238238
let (infcx, param_env) =
239-
self.tcx.infer_ctxt().build_with_typing_env(self.typing_env);
239+
self.tcx.infer_ctxt().build_with_typing_env(ty::TypingEnv {
240+
typing_mode: ty::TypingMode::Reflection,
241+
..self.typing_env
242+
});
240243

241244
let ocx = ObligationCtxt::new(&infcx);
242245
ocx.register_obligations(preds.iter().map(|pred: PolyExistentialPredicate<'_>| {

compiler/rustc_hir/src/hir.rs

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// ignore-tidy-filelength
22
use std::borrow::Cow;
33
use std::fmt;
4+
use std::ops::ControlFlow;
45

56
use rustc_abi::ExternAbi;
67
use rustc_ast::attr::AttributeExt;
@@ -16,6 +17,7 @@ pub use rustc_ast::{
1617
MetaItemInner, MetaItemLit, Movability, Mutability, Pinnedness, UnOp,
1718
};
1819
use rustc_data_structures::fingerprint::Fingerprint;
20+
use rustc_data_structures::fx::FxHashSet;
1921
use rustc_data_structures::sorted_map::SortedMap;
2022
use rustc_data_structures::tagged_ptr::TaggedRef;
2123
use rustc_error_messages::{DiagArgValue, IntoDiagArg};
@@ -35,7 +37,7 @@ use crate::attrs::AttributeKind;
3537
use crate::def::{CtorKind, DefKind, MacroKinds, PerNS, Res};
3638
use crate::def_id::{DefId, LocalDefIdMap};
3739
pub(crate) use crate::hir_id::{HirId, ItemLocalId, ItemLocalMap, OwnerId};
38-
use crate::intravisit::{FnKind, VisitorExt};
40+
use crate::intravisit::{FnKind, Visitor, VisitorExt};
3941
use crate::lints::DelayedLints;
4042

4143
#[derive(Debug, Copy, Clone, PartialEq, Eq, HashStable_Generic)]
@@ -4445,6 +4447,70 @@ pub struct Impl<'hir> {
44454447
pub constness: Constness,
44464448
}
44474449

4450+
impl Impl<'_> {
4451+
pub fn is_fully_generic_for_reflection(&self) -> bool {
4452+
#[derive(Default)]
4453+
struct LifetimeFinder {
4454+
seen: FxHashSet<LocalDefId>,
4455+
}
4456+
impl<'v> Visitor<'v> for LifetimeFinder {
4457+
type Result = ControlFlow<()>;
4458+
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) -> Self::Result {
4459+
match lifetime.kind {
4460+
LifetimeKind::Param(def_id) => {
4461+
if self.seen.insert(def_id) {
4462+
ControlFlow::Continue(())
4463+
} else {
4464+
ControlFlow::Break(())
4465+
}
4466+
}
4467+
LifetimeKind::ImplicitObjectLifetimeDefault
4468+
| LifetimeKind::Error
4469+
| LifetimeKind::Infer
4470+
| LifetimeKind::Static => ControlFlow::Break(()),
4471+
}
4472+
}
4473+
}
4474+
let mut ty_lifetimes = LifetimeFinder::default();
4475+
if ty_lifetimes.visit_ty_unambig(self.self_ty).is_break() {
4476+
return false;
4477+
}
4478+
let ty_lifetimes = ty_lifetimes.seen;
4479+
4480+
#[derive(Default)]
4481+
struct LifetimeChecker {
4482+
ty_lifetimes: FxHashSet<LocalDefId>,
4483+
}
4484+
impl<'v> Visitor<'v> for LifetimeChecker {
4485+
type Result = ControlFlow<()>;
4486+
fn visit_lifetime(&mut self, lifetime: &'v Lifetime) -> Self::Result {
4487+
match lifetime.kind {
4488+
LifetimeKind::Param(def_id) => {
4489+
if self.ty_lifetimes.contains(&def_id) {
4490+
ControlFlow::Break(())
4491+
} else {
4492+
ControlFlow::Continue(())
4493+
}
4494+
}
4495+
LifetimeKind::ImplicitObjectLifetimeDefault
4496+
| LifetimeKind::Error
4497+
| LifetimeKind::Infer
4498+
| LifetimeKind::Static => ControlFlow::Continue(()),
4499+
}
4500+
}
4501+
}
4502+
4503+
let mut checker = LifetimeChecker { ty_lifetimes };
4504+
4505+
// Pessimistic: if any of the lifetimes used in the type show up in where bounds
4506+
// don't allow this impl to be used.
4507+
self.generics
4508+
.predicates
4509+
.iter()
4510+
.all(|pred| checker.visit_where_predicate(pred).is_continue())
4511+
}
4512+
}
4513+
44484514
#[derive(Debug, Clone, Copy, HashStable_Generic)]
44494515
pub struct TraitImplHeader<'hir> {
44504516
pub safety: Safety,

compiler/rustc_hir_analysis/src/collect.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1345,6 +1345,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader
13451345
.unwrap_or_else(|| panic!("expected impl trait, found inherent impl on {def_id:?}"));
13461346
let selfty = tcx.type_of(def_id).instantiate_identity();
13471347
let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl);
1348+
let is_fully_generic_for_reflection = impl_.is_fully_generic_for_reflection();
13481349

13491350
check_impl_constness(tcx, impl_.constness, &of_trait.trait_ref);
13501351

@@ -1355,6 +1356,7 @@ fn impl_trait_header(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::ImplTraitHeader
13551356
safety: of_trait.safety,
13561357
polarity: polarity_of_impl(tcx, of_trait, is_rustc_reservation),
13571358
constness: impl_.constness,
1359+
is_fully_generic_for_reflection,
13581360
}
13591361
}
13601362

compiler/rustc_infer/src/infer/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ impl<'tcx> InferCtxt<'tcx> {
10551055
// and post-borrowck analysis mode. We may need to modify its uses
10561056
// to support PostBorrowckAnalysis in the old solver as well.
10571057
TypingMode::Coherence
1058+
| TypingMode::Reflection
10581059
| TypingMode::PostBorrowckAnalysis { .. }
10591060
| TypingMode::PostAnalysis => false,
10601061
}
@@ -1379,6 +1380,7 @@ impl<'tcx> InferCtxt<'tcx> {
13791380
}
13801381
mode @ (ty::TypingMode::Coherence
13811382
| ty::TypingMode::PostBorrowckAnalysis { .. }
1383+
| ty::TypingMode::Reflection
13821384
| ty::TypingMode::PostAnalysis) => mode,
13831385
};
13841386
ty::TypingEnv { typing_mode, param_env }

compiler/rustc_infer/src/infer/opaque_types/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ impl<'tcx> InferCtxt<'tcx> {
276276
.map(|obligation| obligation.as_goal()),
277277
);
278278
}
279-
mode @ (ty::TypingMode::PostBorrowckAnalysis { .. } | ty::TypingMode::PostAnalysis) => {
279+
mode @ (ty::TypingMode::PostBorrowckAnalysis { .. }
280+
| ty::TypingMode::PostAnalysis
281+
| ty::TypingMode::Reflection) => {
280282
bug!("insert hidden type in {mode:?}")
281283
}
282284
}

compiler/rustc_middle/src/ty/context.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
689689
self.impl_polarity(impl_def_id)
690690
}
691691

692+
fn is_fully_generic_for_reflection(self, impl_def_id: Self::ImplId) -> bool {
693+
self.impl_trait_header(impl_def_id).is_fully_generic_for_reflection
694+
}
695+
692696
fn trait_is_auto(self, trait_def_id: DefId) -> bool {
693697
self.trait_is_auto(trait_def_id)
694698
}

compiler/rustc_middle/src/ty/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ pub struct ImplTraitHeader<'tcx> {
262262
pub polarity: ImplPolarity,
263263
pub safety: hir::Safety,
264264
pub constness: hir::Constness,
265+
/// Whether all generic parameters of the type are unique unconstrained generic parameters
266+
/// of the impl. `Bar<'static>` or `Foo<'a, 'a>` or outlives bounds on the lifetimes cause
267+
/// this boolean to be false and `try_as_dyn` to return `None`.
268+
pub is_fully_generic_for_reflection: bool,
265269
}
266270

267271
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,7 @@ where
928928
TypingMode::Coherence => return,
929929
TypingMode::Analysis { .. }
930930
| TypingMode::Borrowck { .. }
931+
| TypingMode::Reflection
931932
| TypingMode::PostBorrowckAnalysis { .. }
932933
| TypingMode::PostAnalysis => {}
933934
}
@@ -991,6 +992,7 @@ where
991992
TypingMode::Analysis { .. } => self.opaques_with_sub_unified_hidden_type(self_ty),
992993
TypingMode::Coherence
993994
| TypingMode::Borrowck { .. }
995+
| TypingMode::Reflection
994996
| TypingMode::PostBorrowckAnalysis { .. }
995997
| TypingMode::PostAnalysis => vec![],
996998
};

compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ where
142142
TypingMode::Coherence => Certainty::AMBIGUOUS,
143143
TypingMode::Analysis { .. }
144144
| TypingMode::Borrowck { .. }
145+
| TypingMode::Reflection
145146
| TypingMode::PostBorrowckAnalysis { .. }
146147
| TypingMode::PostAnalysis => return Err(NoSolution),
147148
},

compiler/rustc_next_trait_solver/src/solve/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ where
368368
fn opaque_type_is_rigid(&self, def_id: I::DefId) -> bool {
369369
match self.typing_mode() {
370370
// Opaques are never rigid outside of analysis mode.
371-
TypingMode::Coherence | TypingMode::PostAnalysis => false,
371+
TypingMode::Reflection | TypingMode::Coherence | TypingMode::PostAnalysis => false,
372372
// During analysis, opaques are rigid unless they may be defined by
373373
// the current body.
374374
TypingMode::Analysis { defining_opaque_types_and_generators: non_rigid_opaques }

0 commit comments

Comments
 (0)