Skip to content

Commit 921bf33

Browse files
authored
Rollup merge of rust-lang#70658 - davidtwco:issue-70285-still-further-specializable, r=eddyb
add `STILL_FURTHER_SPECIALIZABLE` flag Contributes to rust-lang#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 43b536e + c665eae commit 921bf33

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
@@ -524,101 +524,106 @@ bitflags! {
524524
// Does this have parameters? Used to determine whether substitution is
525525
// required.
526526
/// Does this have [Param]?
527-
const HAS_TY_PARAM = 1 << 0;
527+
const HAS_TY_PARAM = 1 << 0;
528528
/// Does this have [ReEarlyBound]?
529-
const HAS_RE_PARAM = 1 << 1;
529+
const HAS_RE_PARAM = 1 << 1;
530530
/// Does this have [ConstKind::Param]?
531-
const HAS_CT_PARAM = 1 << 2;
531+
const HAS_CT_PARAM = 1 << 2;
532532

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

537537
/// Does this have [Infer]?
538-
const HAS_TY_INFER = 1 << 3;
538+
const HAS_TY_INFER = 1 << 3;
539539
/// Does this have [ReVar]?
540-
const HAS_RE_INFER = 1 << 4;
540+
const HAS_RE_INFER = 1 << 4;
541541
/// Does this have [ConstKind::Infer]?
542-
const HAS_CT_INFER = 1 << 5;
542+
const HAS_CT_INFER = 1 << 5;
543543

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

550550
/// Does this have [Placeholder]?
551-
const HAS_TY_PLACEHOLDER = 1 << 6;
551+
const HAS_TY_PLACEHOLDER = 1 << 6;
552552
/// Does this have [RePlaceholder]?
553-
const HAS_RE_PLACEHOLDER = 1 << 7;
553+
const HAS_RE_PLACEHOLDER = 1 << 7;
554554
/// Does this have [ConstKind::Placeholder]?
555-
const HAS_CT_PLACEHOLDER = 1 << 8;
555+
const HAS_CT_PLACEHOLDER = 1 << 8;
556556

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

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

571571
/// Does this have [Projection] or [UnnormalizedProjection]?
572-
const HAS_TY_PROJECTION = 1 << 10;
572+
const HAS_TY_PROJECTION = 1 << 10;
573573
/// Does this have [Opaque]?
574-
const HAS_TY_OPAQUE = 1 << 11;
574+
const HAS_TY_OPAQUE = 1 << 11;
575575
/// Does this have [ConstKind::Unevaluated]?
576-
const HAS_CT_PROJECTION = 1 << 12;
576+
const HAS_CT_PROJECTION = 1 << 12;
577577

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

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

587587
/// Is an error type reachable?
588-
const HAS_TY_ERR = 1 << 14;
588+
const HAS_TY_ERR = 1 << 14;
589589

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

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

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

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

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)