Skip to content

Commit 857942e

Browse files
authored
Rollup merge of #70658 - davidtwco:issue-70285-still-further-specializable, r=eddyb
add `STILL_FURTHER_SPECIALIZABLE` flag Contributes to #70285. This PR adds a `STILL_FURTHER_SPECIALIZABLE` flag to `TypeFlags` which replaces `needs_infer` and `needs_subst` in `Instance::resolve` and `assemble_candidates_from_impls`. r? @eddyb
2 parents 791e872 + c665eae commit 857942e

File tree

6 files changed

+86
-57
lines changed

6 files changed

+86
-57
lines changed

src/librustc_middle/ty/flags.rs

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::ty::subst::{GenericArgKind, SubstsRef};
1+
use crate::ty::subst::{GenericArg, GenericArgKind};
22
use crate::ty::{self, InferConst, Ty, TypeFlags};
33

44
#[derive(Debug)]
@@ -81,6 +81,7 @@ impl FlagComputation {
8181

8282
&ty::Param(_) => {
8383
self.add_flags(TypeFlags::HAS_TY_PARAM);
84+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
8485
}
8586

8687
&ty::Generator(_, ref substs, _) => {
@@ -99,14 +100,17 @@ impl FlagComputation {
99100

100101
&ty::Bound(debruijn, _) => {
101102
self.add_binder(debruijn);
103+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
102104
}
103105

104106
&ty::Placeholder(..) => {
105107
self.add_flags(TypeFlags::HAS_TY_PLACEHOLDER);
108+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
106109
}
107110

108111
&ty::Infer(infer) => {
109112
self.add_flags(TypeFlags::HAS_TY_INFER);
113+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
110114
match infer {
111115
ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_) => {}
112116

@@ -218,17 +222,23 @@ impl FlagComputation {
218222
}
219223
ty::ConstKind::Infer(infer) => {
220224
self.add_flags(TypeFlags::HAS_CT_INFER);
225+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
221226
match infer {
222227
InferConst::Fresh(_) => {}
223228
InferConst::Var(_) => self.add_flags(TypeFlags::KEEP_IN_LOCAL_TCX),
224229
}
225230
}
226-
ty::ConstKind::Bound(debruijn, _) => self.add_binder(debruijn),
231+
ty::ConstKind::Bound(debruijn, _) => {
232+
self.add_binder(debruijn);
233+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
234+
}
227235
ty::ConstKind::Param(_) => {
228236
self.add_flags(TypeFlags::HAS_CT_PARAM);
237+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
229238
}
230239
ty::ConstKind::Placeholder(_) => {
231240
self.add_flags(TypeFlags::HAS_CT_PLACEHOLDER);
241+
self.add_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
232242
}
233243
ty::ConstKind::Value(_) => {}
234244
}
@@ -243,7 +253,7 @@ impl FlagComputation {
243253
self.add_substs(projection_ty.substs);
244254
}
245255

246-
fn add_substs(&mut self, substs: SubstsRef<'_>) {
256+
fn add_substs(&mut self, substs: &[GenericArg<'_>]) {
247257
for kind in substs {
248258
match kind.unpack() {
249259
GenericArgKind::Type(ty) => self.add_ty(ty),

src/librustc_middle/ty/fold.rs

+7
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,13 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
142142
self.has_type_flags(TypeFlags::HAS_RE_LATE_BOUND)
143143
}
144144

145+
/// Indicates whether this value still has parameters/placeholders/inference variables
146+
/// which could be replaced later, in a way that would change the results of `impl`
147+
/// specialization.
148+
fn still_further_specializable(&self) -> bool {
149+
self.has_type_flags(TypeFlags::STILL_FURTHER_SPECIALIZABLE)
150+
}
151+
145152
/// A visitor that does not recurse into types, works like `fn walk_shallow` in `Ty`.
146153
fn visit_tys_shallow(&self, visit: impl FnMut(Ty<'tcx>) -> bool) -> bool {
147154
pub struct Visitor<F>(F);

src/librustc_middle/ty/mod.rs

+57-52
Original file line numberDiff line numberDiff line change
@@ -523,101 +523,106 @@ bitflags! {
523523
// Does this have parameters? Used to determine whether substitution is
524524
// required.
525525
/// Does this have [Param]?
526-
const HAS_TY_PARAM = 1 << 0;
526+
const HAS_TY_PARAM = 1 << 0;
527527
/// Does this have [ReEarlyBound]?
528-
const HAS_RE_PARAM = 1 << 1;
528+
const HAS_RE_PARAM = 1 << 1;
529529
/// Does this have [ConstKind::Param]?
530-
const HAS_CT_PARAM = 1 << 2;
530+
const HAS_CT_PARAM = 1 << 2;
531531

532-
const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits
533-
| TypeFlags::HAS_RE_PARAM.bits
534-
| TypeFlags::HAS_CT_PARAM.bits;
532+
const NEEDS_SUBST = TypeFlags::HAS_TY_PARAM.bits
533+
| TypeFlags::HAS_RE_PARAM.bits
534+
| TypeFlags::HAS_CT_PARAM.bits;
535535

536536
/// Does this have [Infer]?
537-
const HAS_TY_INFER = 1 << 3;
537+
const HAS_TY_INFER = 1 << 3;
538538
/// Does this have [ReVar]?
539-
const HAS_RE_INFER = 1 << 4;
539+
const HAS_RE_INFER = 1 << 4;
540540
/// Does this have [ConstKind::Infer]?
541-
const HAS_CT_INFER = 1 << 5;
541+
const HAS_CT_INFER = 1 << 5;
542542

543543
/// Does this have inference variables? Used to determine whether
544544
/// inference is required.
545-
const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits
546-
| TypeFlags::HAS_RE_INFER.bits
547-
| TypeFlags::HAS_CT_INFER.bits;
545+
const NEEDS_INFER = TypeFlags::HAS_TY_INFER.bits
546+
| TypeFlags::HAS_RE_INFER.bits
547+
| TypeFlags::HAS_CT_INFER.bits;
548548

549549
/// Does this have [Placeholder]?
550-
const HAS_TY_PLACEHOLDER = 1 << 6;
550+
const HAS_TY_PLACEHOLDER = 1 << 6;
551551
/// Does this have [RePlaceholder]?
552-
const HAS_RE_PLACEHOLDER = 1 << 7;
552+
const HAS_RE_PLACEHOLDER = 1 << 7;
553553
/// Does this have [ConstKind::Placeholder]?
554-
const HAS_CT_PLACEHOLDER = 1 << 8;
554+
const HAS_CT_PLACEHOLDER = 1 << 8;
555555

556556
/// `true` if there are "names" of regions and so forth
557557
/// that are local to a particular fn/inferctxt
558-
const HAS_FREE_LOCAL_REGIONS = 1 << 9;
558+
const HAS_FREE_LOCAL_REGIONS = 1 << 9;
559559

560560
/// `true` if there are "names" of types and regions and so forth
561561
/// that are local to a particular fn
562-
const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits
563-
| TypeFlags::HAS_CT_PARAM.bits
564-
| TypeFlags::HAS_TY_INFER.bits
565-
| TypeFlags::HAS_CT_INFER.bits
566-
| TypeFlags::HAS_TY_PLACEHOLDER.bits
567-
| TypeFlags::HAS_CT_PLACEHOLDER.bits
568-
| TypeFlags::HAS_FREE_LOCAL_REGIONS.bits;
562+
const HAS_FREE_LOCAL_NAMES = TypeFlags::HAS_TY_PARAM.bits
563+
| TypeFlags::HAS_CT_PARAM.bits
564+
| TypeFlags::HAS_TY_INFER.bits
565+
| TypeFlags::HAS_CT_INFER.bits
566+
| TypeFlags::HAS_TY_PLACEHOLDER.bits
567+
| TypeFlags::HAS_CT_PLACEHOLDER.bits
568+
| TypeFlags::HAS_FREE_LOCAL_REGIONS.bits;
569569

570570
/// Does this have [Projection] or [UnnormalizedProjection]?
571-
const HAS_TY_PROJECTION = 1 << 10;
571+
const HAS_TY_PROJECTION = 1 << 10;
572572
/// Does this have [Opaque]?
573-
const HAS_TY_OPAQUE = 1 << 11;
573+
const HAS_TY_OPAQUE = 1 << 11;
574574
/// Does this have [ConstKind::Unevaluated]?
575-
const HAS_CT_PROJECTION = 1 << 12;
575+
const HAS_CT_PROJECTION = 1 << 12;
576576

577577
/// Could this type be normalized further?
578-
const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits
579-
| TypeFlags::HAS_TY_OPAQUE.bits
580-
| TypeFlags::HAS_CT_PROJECTION.bits;
578+
const HAS_PROJECTION = TypeFlags::HAS_TY_PROJECTION.bits
579+
| TypeFlags::HAS_TY_OPAQUE.bits
580+
| TypeFlags::HAS_CT_PROJECTION.bits;
581581

582582
/// Present if the type belongs in a local type context.
583583
/// Set for placeholders and inference variables that are not "Fresh".
584-
const KEEP_IN_LOCAL_TCX = 1 << 13;
584+
const KEEP_IN_LOCAL_TCX = 1 << 13;
585585

586586
/// Is an error type reachable?
587-
const HAS_TY_ERR = 1 << 14;
587+
const HAS_TY_ERR = 1 << 14;
588588

589589
/// Does this have any region that "appears free" in the type?
590590
/// Basically anything but [ReLateBound] and [ReErased].
591-
const HAS_FREE_REGIONS = 1 << 15;
591+
const HAS_FREE_REGIONS = 1 << 15;
592592

593593
/// Does this have any [ReLateBound] regions? Used to check
594594
/// if a global bound is safe to evaluate.
595-
const HAS_RE_LATE_BOUND = 1 << 16;
595+
const HAS_RE_LATE_BOUND = 1 << 16;
596596

597597
/// Does this have any [ReErased] regions?
598-
const HAS_RE_ERASED = 1 << 17;
598+
const HAS_RE_ERASED = 1 << 17;
599+
600+
/// Does this value have parameters/placeholders/inference variables which could be
601+
/// replaced later, in a way that would change the results of `impl` specialization?
602+
const STILL_FURTHER_SPECIALIZABLE = 1 << 18;
599603

600604
/// Flags representing the nominal content of a type,
601605
/// computed by FlagsComputation. If you add a new nominal
602606
/// flag, it should be added here too.
603-
const NOMINAL_FLAGS = TypeFlags::HAS_TY_PARAM.bits
604-
| TypeFlags::HAS_RE_PARAM.bits
605-
| TypeFlags::HAS_CT_PARAM.bits
606-
| TypeFlags::HAS_TY_INFER.bits
607-
| TypeFlags::HAS_RE_INFER.bits
608-
| TypeFlags::HAS_CT_INFER.bits
609-
| TypeFlags::HAS_TY_PLACEHOLDER.bits
610-
| TypeFlags::HAS_RE_PLACEHOLDER.bits
611-
| TypeFlags::HAS_CT_PLACEHOLDER.bits
612-
| TypeFlags::HAS_FREE_LOCAL_REGIONS.bits
613-
| TypeFlags::HAS_TY_PROJECTION.bits
614-
| TypeFlags::HAS_TY_OPAQUE.bits
615-
| TypeFlags::HAS_CT_PROJECTION.bits
616-
| TypeFlags::KEEP_IN_LOCAL_TCX.bits
617-
| TypeFlags::HAS_TY_ERR.bits
618-
| TypeFlags::HAS_FREE_REGIONS.bits
619-
| TypeFlags::HAS_RE_LATE_BOUND.bits
620-
| TypeFlags::HAS_RE_ERASED.bits;
607+
const NOMINAL_FLAGS = TypeFlags::HAS_TY_PARAM.bits
608+
| TypeFlags::HAS_RE_PARAM.bits
609+
| TypeFlags::HAS_CT_PARAM.bits
610+
| TypeFlags::HAS_TY_INFER.bits
611+
| TypeFlags::HAS_RE_INFER.bits
612+
| TypeFlags::HAS_CT_INFER.bits
613+
| TypeFlags::HAS_TY_PLACEHOLDER.bits
614+
| TypeFlags::HAS_RE_PLACEHOLDER.bits
615+
| TypeFlags::HAS_CT_PLACEHOLDER.bits
616+
| TypeFlags::HAS_FREE_LOCAL_REGIONS.bits
617+
| TypeFlags::HAS_TY_PROJECTION.bits
618+
| TypeFlags::HAS_TY_OPAQUE.bits
619+
| TypeFlags::HAS_CT_PROJECTION.bits
620+
| TypeFlags::KEEP_IN_LOCAL_TCX.bits
621+
| TypeFlags::HAS_TY_ERR.bits
622+
| TypeFlags::HAS_FREE_REGIONS.bits
623+
| TypeFlags::HAS_RE_LATE_BOUND.bits
624+
| TypeFlags::HAS_RE_ERASED.bits
625+
| TypeFlags::STILL_FURTHER_SPECIALIZABLE.bits;
621626
}
622627
}
623628

src/librustc_middle/ty/sty.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1623,16 +1623,19 @@ impl RegionKind {
16231623
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
16241624
flags = flags | TypeFlags::HAS_RE_INFER;
16251625
flags = flags | TypeFlags::KEEP_IN_LOCAL_TCX;
1626+
flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
16261627
}
16271628
ty::RePlaceholder(..) => {
16281629
flags = flags | TypeFlags::HAS_FREE_REGIONS;
16291630
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
16301631
flags = flags | TypeFlags::HAS_RE_PLACEHOLDER;
1632+
flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
16311633
}
16321634
ty::ReEarlyBound(..) => {
16331635
flags = flags | TypeFlags::HAS_FREE_REGIONS;
16341636
flags = flags | TypeFlags::HAS_FREE_LOCAL_REGIONS;
16351637
flags = flags | TypeFlags::HAS_RE_PARAM;
1638+
flags = flags | TypeFlags::STILL_FURTHER_SPECIALIZABLE;
16361639
}
16371640
ty::ReFree { .. } | ty::ReScope { .. } => {
16381641
flags = flags | TypeFlags::HAS_FREE_REGIONS;

src/librustc_trait_selection/traits/project.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1028,7 +1028,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
10281028
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
10291029
let poly_trait_ref =
10301030
selcx.infcx().resolve_vars_if_possible(&poly_trait_ref);
1031-
!poly_trait_ref.needs_infer() && !poly_trait_ref.needs_subst()
1031+
!poly_trait_ref.still_further_specializable()
10321032
} else {
10331033
debug!(
10341034
"assemble_candidates_from_impls: not eligible due to default: \

src/librustc_ty/instance.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,11 @@ fn resolve_associated_item<'tcx>(
127127
// and the obligation is monomorphic, otherwise passes such as
128128
// transmute checking and polymorphic MIR optimizations could
129129
// get a result which isn't correct for all monomorphizations.
130-
if param_env.reveal == Reveal::All { !trait_ref.needs_subst() } else { false }
130+
if param_env.reveal == Reveal::All {
131+
!trait_ref.still_further_specializable()
132+
} else {
133+
false
134+
}
131135
};
132136

133137
if !eligible {

0 commit comments

Comments
 (0)