Skip to content

Commit 2fba17f

Browse files
committed
Auto merge of #56837 - arielb1:nonprincipal-trait-objects, r=nikomatsakis
Add support for trait-objects without a principal The hard-error version of #56481 - should be merged after we do something about the `traitobject` crate. Fixes #33140. Fixes #57057. r? @nikomatsakis
2 parents 244b05d + c213b0d commit 2fba17f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+815
-453
lines changed

src/librustc/dep_graph/dep_node.rs

+1
Original file line numberDiff line numberDiff line change
@@ -492,6 +492,7 @@ define_dep_nodes!( <'tcx>
492492
[] AdtDefOfItem(DefId),
493493
[] ImplTraitRef(DefId),
494494
[] ImplPolarity(DefId),
495+
[] Issue33140SelfTy(DefId),
495496
[] FnSignature(DefId),
496497
[] CoerceUnsizedInfo(DefId),
497498

src/librustc/infer/combine.rs

-4
Original file line numberDiff line numberDiff line change
@@ -337,10 +337,6 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
337337
self.infcx.tcx
338338
}
339339

340-
fn trait_object_mode(&self) -> relate::TraitObjectMode {
341-
self.infcx.trait_object_mode()
342-
}
343-
344340
fn tag(&self) -> &'static str {
345341
"Generalizer"
346342
}

src/librustc/infer/equate.rs

-4
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
2929

3030
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
3131

32-
fn trait_object_mode(&self) -> relate::TraitObjectMode {
33-
self.fields.infcx.trait_object_mode()
34-
}
35-
3632
fn a_is_expected(&self) -> bool { self.a_is_expected }
3733

3834
fn relate_item_substs(&mut self,

src/librustc/infer/glb.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::Subtype;
55

66
use traits::ObligationCause;
77
use ty::{self, Ty, TyCtxt};
8-
use ty::relate::{self, Relate, RelateResult, TypeRelation};
8+
use ty::relate::{Relate, RelateResult, TypeRelation};
99

1010
/// "Greatest lower bound" (common subtype)
1111
pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
@@ -26,10 +26,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
2626
{
2727
fn tag(&self) -> &'static str { "Glb" }
2828

29-
fn trait_object_mode(&self) -> relate::TraitObjectMode {
30-
self.fields.infcx.trait_object_mode()
31-
}
32-
3329
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
3430

3531
fn a_is_expected(&self) -> bool { self.a_is_expected }

src/librustc/infer/lub.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use super::Subtype;
55

66
use traits::ObligationCause;
77
use ty::{self, Ty, TyCtxt};
8-
use ty::relate::{self, Relate, RelateResult, TypeRelation};
8+
use ty::relate::{Relate, RelateResult, TypeRelation};
99

1010
/// "Least upper bound" (common supertype)
1111
pub struct Lub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
@@ -26,10 +26,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
2626
{
2727
fn tag(&self) -> &'static str { "Lub" }
2828

29-
fn trait_object_mode(&self) -> relate::TraitObjectMode {
30-
self.fields.infcx.trait_object_mode()
31-
}
32-
3329
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
3430

3531
fn a_is_expected(&self) -> bool { self.a_is_expected }

src/librustc/infer/mod.rs

+1-18
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use syntax_pos::{self, Span};
2525
use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
2626
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
2727
use ty::fold::TypeFoldable;
28-
use ty::relate::{RelateResult, TraitObjectMode};
28+
use ty::relate::RelateResult;
2929
use ty::subst::{Kind, Substs};
3030
use ty::{self, GenericParamDefKind, Ty, TyCtxt, CtxtInterners};
3131
use ty::{FloatVid, IntVid, TyVid};
@@ -171,9 +171,6 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
171171
// This flag is true while there is an active snapshot.
172172
in_snapshot: Cell<bool>,
173173

174-
// The TraitObjectMode used here,
175-
trait_object_mode: TraitObjectMode,
176-
177174
// A set of constraints that regionck must validate. Each
178175
// constraint has the form `T:'a`, meaning "some type `T` must
179176
// outlive the lifetime 'a". These constraints derive from
@@ -465,7 +462,6 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
465462
arena: SyncDroplessArena,
466463
interners: Option<CtxtInterners<'tcx>>,
467464
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
468-
trait_object_mode: TraitObjectMode,
469465
}
470466

471467
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
@@ -475,7 +471,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
475471
arena: SyncDroplessArena::default(),
476472
interners: None,
477473
fresh_tables: None,
478-
trait_object_mode: TraitObjectMode::NoSquash,
479474
}
480475
}
481476
}
@@ -488,12 +483,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
488483
self
489484
}
490485

491-
pub fn with_trait_object_mode(mut self, mode: TraitObjectMode) -> Self {
492-
debug!("with_trait_object_mode: setting mode to {:?}", mode);
493-
self.trait_object_mode = mode;
494-
self
495-
}
496-
497486
/// Given a canonical value `C` as a starting point, create an
498487
/// inference context that contains each of the bound values
499488
/// within instantiated as a fresh variable. The `f` closure is
@@ -520,7 +509,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
520509
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R {
521510
let InferCtxtBuilder {
522511
global_tcx,
523-
trait_object_mode,
524512
ref arena,
525513
ref mut interners,
526514
ref fresh_tables,
@@ -532,7 +520,6 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
532520
f(InferCtxt {
533521
tcx,
534522
in_progress_tables,
535-
trait_object_mode,
536523
projection_cache: Default::default(),
537524
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
538525
int_unification_table: RefCell::new(ut::UnificationTable::new()),
@@ -614,10 +601,6 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
614601
self.in_snapshot.get()
615602
}
616603

617-
pub fn trait_object_mode(&self) -> TraitObjectMode {
618-
self.trait_object_mode
619-
}
620-
621604
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
622605
t.fold_with(&mut self.freshener())
623606
}

src/librustc/infer/nll_relate/mod.rs

-14
Original file line numberDiff line numberDiff line change
@@ -372,13 +372,6 @@ where
372372
self.infcx.tcx
373373
}
374374

375-
fn trait_object_mode(&self) -> relate::TraitObjectMode {
376-
// squashing should only be done in coherence, not NLL
377-
assert_eq!(self.infcx.trait_object_mode(),
378-
relate::TraitObjectMode::NoSquash);
379-
relate::TraitObjectMode::NoSquash
380-
}
381-
382375
fn tag(&self) -> &'static str {
383376
"nll::subtype"
384377
}
@@ -693,13 +686,6 @@ where
693686
self.infcx.tcx
694687
}
695688

696-
fn trait_object_mode(&self) -> relate::TraitObjectMode {
697-
// squashing should only be done in coherence, not NLL
698-
assert_eq!(self.infcx.trait_object_mode(),
699-
relate::TraitObjectMode::NoSquash);
700-
relate::TraitObjectMode::NoSquash
701-
}
702-
703689
fn tag(&self) -> &'static str {
704690
"nll::generalizer"
705691
}

src/librustc/infer/sub.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use traits::Obligation;
55
use ty::{self, Ty, TyCtxt};
66
use ty::TyVar;
77
use ty::fold::TypeFoldable;
8-
use ty::relate::{self, Cause, Relate, RelateResult, TypeRelation};
8+
use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
99
use std::mem;
1010

1111
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
@@ -33,10 +33,6 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
3333
for Sub<'combine, 'infcx, 'gcx, 'tcx>
3434
{
3535
fn tag(&self) -> &'static str { "Sub" }
36-
fn trait_object_mode(&self) -> relate::TraitObjectMode {
37-
self.fields.infcx.trait_object_mode()
38-
}
39-
4036
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.infcx.tcx }
4137
fn a_is_expected(&self) -> bool { self.a_is_expected }
4238

src/librustc/traits/coherence.rs

+11-9
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
1111
use traits::IntercrateMode;
1212
use traits::select::IntercrateAmbiguityCause;
1313
use ty::{self, Ty, TyCtxt};
14-
use ty::relate::TraitObjectMode;
1514
use ty::fold::TypeFoldable;
1615
use ty::subst::Subst;
1716

@@ -55,7 +54,6 @@ pub fn overlapping_impls<'gcx, F1, F2, R>(
5554
impl1_def_id: DefId,
5655
impl2_def_id: DefId,
5756
intercrate_mode: IntercrateMode,
58-
trait_object_mode: TraitObjectMode,
5957
on_overlap: F1,
6058
no_overlap: F2,
6159
) -> R
@@ -66,14 +64,12 @@ where
6664
debug!("overlapping_impls(\
6765
impl1_def_id={:?}, \
6866
impl2_def_id={:?},
69-
intercrate_mode={:?},
70-
trait_object_mode={:?})",
67+
intercrate_mode={:?})",
7168
impl1_def_id,
7269
impl2_def_id,
73-
intercrate_mode,
74-
trait_object_mode);
70+
intercrate_mode);
7571

76-
let overlaps = tcx.infer_ctxt().with_trait_object_mode(trait_object_mode).enter(|infcx| {
72+
let overlaps = tcx.infer_ctxt().enter(|infcx| {
7773
let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
7874
overlap(selcx, impl1_def_id, impl2_def_id).is_some()
7975
});
@@ -85,7 +81,7 @@ where
8581
// In the case where we detect an error, run the check again, but
8682
// this time tracking intercrate ambuiguity causes for better
8783
// diagnostics. (These take time and can lead to false errors.)
88-
tcx.infer_ctxt().with_trait_object_mode(trait_object_mode).enter(|infcx| {
84+
tcx.infer_ctxt().enter(|infcx| {
8985
let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
9086
selcx.enable_tracking_intercrate_ambiguity_causes();
9187
on_overlap(overlap(selcx, impl1_def_id, impl2_def_id).unwrap())
@@ -510,7 +506,13 @@ fn ty_is_local_constructor(ty: Ty<'_>, in_crate: InCrate) -> bool {
510506
ty::Adt(def, _) => def_id_is_local(def.did, in_crate),
511507
ty::Foreign(did) => def_id_is_local(did, in_crate),
512508

513-
ty::Dynamic(ref tt, ..) => def_id_is_local(tt.principal().def_id(), in_crate),
509+
ty::Dynamic(ref tt, ..) => {
510+
if let Some(principal) = tt.principal() {
511+
def_id_is_local(principal.def_id(), in_crate)
512+
} else {
513+
false
514+
}
515+
}
514516

515517
ty::Error => true,
516518

src/librustc/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
447447
{
448448
let simp = fast_reject::simplify_type(self.tcx,
449449
trait_ref.skip_binder().self_ty(),
450-
true,);
450+
true);
451451
let all_impls = self.tcx.all_impls(trait_ref.def_id());
452452

453453
match simp {

src/librustc/traits/select.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ use infer::{InferCtxt, InferOk, TypeFreshener};
3333
use middle::lang_items;
3434
use mir::interpret::GlobalId;
3535
use ty::fast_reject;
36-
use ty::relate::{TypeRelation, TraitObjectMode};
36+
use ty::relate::TypeRelation;
3737
use ty::subst::{Subst, Substs};
3838
use ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
3939

@@ -1416,13 +1416,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
14161416
return false;
14171417
}
14181418

1419-
// Same idea as the above, but for alt trait object modes. These
1420-
// should only be used in intercrate mode - better safe than sorry.
1421-
if self.infcx.trait_object_mode() != TraitObjectMode::NoSquash {
1422-
bug!("using squashing TraitObjectMode outside of intercrate mode? param_env={:?}",
1423-
param_env);
1424-
}
1425-
14261419
// Otherwise, we can use the global cache.
14271420
true
14281421
}
@@ -2016,7 +2009,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
20162009
return;
20172010
}
20182011

2019-
data.principal().with_self_ty(self.tcx(), self_ty)
2012+
if let Some(principal) = data.principal() {
2013+
principal.with_self_ty(self.tcx(), self_ty)
2014+
} else {
2015+
// Only auto-trait bounds exist.
2016+
return;
2017+
}
20202018
}
20212019
ty::Infer(ty::TyVar(_)) => {
20222020
debug!("assemble_candidates_from_object_ty: ambiguous");
@@ -2108,7 +2106,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
21082106
//
21092107
// We always upcast when we can because of reason
21102108
// #2 (region bounds).
2111-
data_a.principal().def_id() == data_b.principal().def_id()
2109+
data_a.principal_def_id() == data_b.principal_def_id()
21122110
&& data_b.auto_traits()
21132111
// All of a's auto traits need to be in b's auto traits.
21142112
.all(|b| data_a.auto_traits().any(|a| a == b))
@@ -2262,7 +2260,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
22622260
ImplCandidate(victim_def) => {
22632261
let tcx = self.tcx().global_tcx();
22642262
return tcx.specializes((other_def, victim_def))
2265-
|| tcx.impls_are_allowed_to_overlap(other_def, victim_def);
2263+
|| tcx.impls_are_allowed_to_overlap(
2264+
other_def, victim_def).is_some();
22662265
}
22672266
ParamCandidate(ref cand) => {
22682267
// Prefer the impl to a global where clause candidate.
@@ -2919,7 +2918,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
29192918
let self_ty = self.infcx
29202919
.shallow_resolve(*obligation.self_ty().skip_binder());
29212920
let poly_trait_ref = match self_ty.sty {
2922-
ty::Dynamic(ref data, ..) => data.principal().with_self_ty(self.tcx(), self_ty),
2921+
ty::Dynamic(ref data, ..) =>
2922+
data.principal().unwrap_or_else(|| {
2923+
span_bug!(obligation.cause.span, "object candidate with no principal")
2924+
}).with_self_ty(self.tcx(), self_ty),
29232925
_ => span_bug!(obligation.cause.span, "object candidate with non-object"),
29242926
};
29252927

@@ -3222,8 +3224,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
32223224
(&ty::Dynamic(ref data_a, r_a), &ty::Dynamic(ref data_b, r_b)) => {
32233225
// See assemble_candidates_for_unsizing for more info.
32243226
let existential_predicates = data_a.map_bound(|data_a| {
3225-
let iter = iter::once(ty::ExistentialPredicate::Trait(data_a.principal()))
3226-
.chain(
3227+
let iter =
3228+
data_a.principal().map(|x| ty::ExistentialPredicate::Trait(x))
3229+
.into_iter().chain(
32273230
data_a
32283231
.projection_bounds()
32293232
.map(|x| ty::ExistentialPredicate::Projection(x)),
@@ -3260,7 +3263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
32603263
// T -> Trait.
32613264
(_, &ty::Dynamic(ref data, r)) => {
32623265
let mut object_dids = data.auto_traits()
3263-
.chain(iter::once(data.principal().def_id()));
3266+
.chain(data.principal_def_id());
32643267
if let Some(did) = object_dids.find(|did| !tcx.is_object_safe(*did)) {
32653268
return Err(TraitNotObjectSafe(did));
32663269
}
@@ -3571,8 +3574,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
35713574
previous: &ty::PolyTraitRef<'tcx>,
35723575
current: &ty::PolyTraitRef<'tcx>,
35733576
) -> bool {
3574-
let mut matcher = ty::_match::Match::new(
3575-
self.tcx(), self.infcx.trait_object_mode());
3577+
let mut matcher = ty::_match::Match::new(self.tcx());
35763578
matcher.relate(previous, current).is_ok()
35773579
}
35783580

src/librustc/traits/specialize/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ pub mod specialization_graph;
1414
use hir::def_id::DefId;
1515
use infer::{InferCtxt, InferOk};
1616
use lint;
17-
use traits::{self, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
18-
use traits::coherence;
17+
use traits::{self, coherence, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
1918
use rustc_data_structures::fx::FxHashSet;
2019
use rustc_data_structures::sync::Lrc;
2120
use syntax_pos::DUMMY_SP;

0 commit comments

Comments
 (0)