Skip to content

Commit 7606396

Browse files
committed
add coherence future-compat warnings for marker-only trait objects
The future-compat warnings break code that assumes that `dyn Send + Sync != dyn Sync + Send`, and are the first step in making them equal. cc rust-lang#33140. It should be possible to revert this commit when we're done with the warnings.
1 parent 3882567 commit 7606396

File tree

21 files changed

+433
-56
lines changed

21 files changed

+433
-56
lines changed

src/librustc/infer/combine.rs

+4
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,10 @@ impl<'cx, 'gcx, 'tcx> TypeRelation<'cx, 'gcx, 'tcx> for Generalizer<'cx, 'gcx, '
347347
self.infcx.tcx
348348
}
349349

350+
fn trait_object_mode(&self) -> relate::TraitObjectMode {
351+
self.infcx.trait_object_mode()
352+
}
353+
350354
fn tag(&self) -> &'static str {
351355
"Generalizer"
352356
}

src/librustc/infer/equate.rs

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

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

42+
fn trait_object_mode(&self) -> relate::TraitObjectMode {
43+
self.fields.infcx.trait_object_mode()
44+
}
45+
4246
fn a_is_expected(&self) -> bool { self.a_is_expected }
4347

4448
fn relate_item_substs(&mut self,

src/librustc/infer/glb.rs

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

1616
use traits::ObligationCause;
1717
use ty::{self, Ty, TyCtxt};
18-
use ty::relate::{Relate, RelateResult, TypeRelation};
18+
use ty::relate::{self, Relate, RelateResult, TypeRelation};
1919

2020
/// "Greatest lower bound" (common subtype)
2121
pub struct Glb<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
@@ -36,6 +36,10 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
3636
{
3737
fn tag(&self) -> &'static str { "Glb" }
3838

39+
fn trait_object_mode(&self) -> relate::TraitObjectMode {
40+
self.fields.infcx.trait_object_mode()
41+
}
42+
3943
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
4044

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

src/librustc/infer/lub.rs

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

1616
use traits::ObligationCause;
1717
use ty::{self, Ty, TyCtxt};
18-
use ty::relate::{Relate, RelateResult, TypeRelation};
18+
use ty::relate::{self, Relate, RelateResult, TypeRelation};
1919

2020
/// "Least upper bound" (common supertype)
2121
pub struct Lub<'combine, 'infcx: 'combine, 'gcx: 'infcx+'tcx, 'tcx: 'infcx> {
@@ -36,6 +36,10 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
3636
{
3737
fn tag(&self) -> &'static str { "Lub" }
3838

39+
fn trait_object_mode(&self) -> relate::TraitObjectMode {
40+
self.fields.infcx.trait_object_mode()
41+
}
42+
3943
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.tcx() }
4044

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

src/librustc/infer/mod.rs

+18-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ use syntax_pos::{self, Span};
3535
use traits::{self, ObligationCause, PredicateObligations, TraitEngine};
3636
use ty::error::{ExpectedFound, TypeError, UnconstrainedNumeric};
3737
use ty::fold::TypeFoldable;
38-
use ty::relate::RelateResult;
38+
use ty::relate::{RelateResult, TraitObjectMode};
3939
use ty::subst::{Kind, Substs};
4040
use ty::{self, GenericParamDefKind, Ty, TyCtxt};
4141
use ty::{FloatVid, IntVid, TyVid};
@@ -182,6 +182,9 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
182182
// This flag is true while there is an active snapshot.
183183
in_snapshot: Cell<bool>,
184184

185+
// The TraitObjectMode used here,
186+
trait_object_mode: TraitObjectMode,
187+
185188
// A set of constraints that regionck must validate. Each
186189
// constraint has the form `T:'a`, meaning "some type `T` must
187190
// outlive the lifetime 'a". These constraints derive from
@@ -472,6 +475,7 @@ pub struct InferCtxtBuilder<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
472475
global_tcx: TyCtxt<'a, 'gcx, 'gcx>,
473476
arena: SyncDroplessArena,
474477
fresh_tables: Option<RefCell<ty::TypeckTables<'tcx>>>,
478+
trait_object_mode: TraitObjectMode,
475479
}
476480

477481
impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
@@ -480,6 +484,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
480484
global_tcx: self,
481485
arena: SyncDroplessArena::default(),
482486
fresh_tables: None,
487+
trait_object_mode: TraitObjectMode::NoSquash,
483488
}
484489
}
485490
}
@@ -492,6 +497,12 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
492497
self
493498
}
494499

500+
pub fn with_trait_object_mode(mut self, mode: TraitObjectMode) -> Self {
501+
debug!("with_trait_object_mode: setting mode to {:?}", mode);
502+
self.trait_object_mode = mode;
503+
self
504+
}
505+
495506
/// Given a canonical value `C` as a starting point, create an
496507
/// inference context that contains each of the bound values
497508
/// within instantiated as a fresh variable. The `f` closure is
@@ -518,6 +529,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
518529
pub fn enter<R>(&'tcx mut self, f: impl for<'b> FnOnce(InferCtxt<'b, 'gcx, 'tcx>) -> R) -> R {
519530
let InferCtxtBuilder {
520531
global_tcx,
532+
trait_object_mode,
521533
ref arena,
522534
ref fresh_tables,
523535
} = *self;
@@ -526,6 +538,7 @@ impl<'a, 'gcx, 'tcx> InferCtxtBuilder<'a, 'gcx, 'tcx> {
526538
f(InferCtxt {
527539
tcx,
528540
in_progress_tables,
541+
trait_object_mode,
529542
projection_cache: Default::default(),
530543
type_variables: RefCell::new(type_variable::TypeVariableTable::new()),
531544
int_unification_table: RefCell::new(ut::UnificationTable::new()),
@@ -607,6 +620,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
607620
self.in_snapshot.get()
608621
}
609622

623+
pub fn trait_object_mode(&self) -> TraitObjectMode {
624+
self.trait_object_mode
625+
}
626+
610627
pub fn freshen<T: TypeFoldable<'tcx>>(&self, t: T) -> T {
611628
t.fold_with(&mut self.freshener())
612629
}

src/librustc/infer/nll_relate/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,13 @@ where
382382
self.infcx.tcx
383383
}
384384

385+
fn trait_object_mode(&self) -> relate::TraitObjectMode {
386+
// squashing should only be done in coherence, not NLL
387+
assert_eq!(self.infcx.trait_object_mode(),
388+
relate::TraitObjectMode::NoSquash);
389+
relate::TraitObjectMode::NoSquash
390+
}
391+
385392
fn tag(&self) -> &'static str {
386393
"nll::subtype"
387394
}
@@ -696,6 +703,13 @@ where
696703
self.infcx.tcx
697704
}
698705

706+
fn trait_object_mode(&self) -> relate::TraitObjectMode {
707+
// squashing should only be done in coherence, not NLL
708+
assert_eq!(self.infcx.trait_object_mode(),
709+
relate::TraitObjectMode::NoSquash);
710+
relate::TraitObjectMode::NoSquash
711+
}
712+
699713
fn tag(&self) -> &'static str {
700714
"nll::generalizer"
701715
}

src/librustc/infer/sub.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use traits::Obligation;
1515
use ty::{self, Ty, TyCtxt};
1616
use ty::TyVar;
1717
use ty::fold::TypeFoldable;
18-
use ty::relate::{Cause, Relate, RelateResult, TypeRelation};
18+
use ty::relate::{self, Cause, Relate, RelateResult, TypeRelation};
1919
use std::mem;
2020

2121
/// Ensures `a` is made a subtype of `b`. Returns `a` on success.
@@ -43,6 +43,10 @@ impl<'combine, 'infcx, 'gcx, 'tcx> TypeRelation<'infcx, 'gcx, 'tcx>
4343
for Sub<'combine, 'infcx, 'gcx, 'tcx>
4444
{
4545
fn tag(&self) -> &'static str { "Sub" }
46+
fn trait_object_mode(&self) -> relate::TraitObjectMode {
47+
self.fields.infcx.trait_object_mode()
48+
}
49+
4650
fn tcx(&self) -> TyCtxt<'infcx, 'gcx, 'tcx> { self.fields.infcx.tcx }
4751
fn a_is_expected(&self) -> bool { self.a_is_expected }
4852

src/librustc/traits/coherence.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use traits::{self, Normalized, SelectionContext, Obligation, ObligationCause};
2020
use traits::IntercrateMode;
2121
use traits::select::IntercrateAmbiguityCause;
2222
use ty::{self, Ty, TyCtxt};
23+
use ty::relate::TraitObjectMode;
2324
use ty::fold::TypeFoldable;
2425
use ty::subst::Subst;
2526

@@ -52,6 +53,7 @@ pub fn overlapping_impls<'gcx, F1, F2, R>(
5253
impl1_def_id: DefId,
5354
impl2_def_id: DefId,
5455
intercrate_mode: IntercrateMode,
56+
trait_object_mode: TraitObjectMode,
5557
on_overlap: F1,
5658
no_overlap: F2,
5759
) -> R
@@ -62,12 +64,14 @@ where
6264
debug!("overlapping_impls(\
6365
impl1_def_id={:?}, \
6466
impl2_def_id={:?},
65-
intercrate_mode={:?})",
67+
intercrate_mode={:?},
68+
trait_object_mode={:?})",
6669
impl1_def_id,
6770
impl2_def_id,
68-
intercrate_mode);
71+
intercrate_mode,
72+
trait_object_mode);
6973

70-
let overlaps = tcx.infer_ctxt().enter(|infcx| {
74+
let overlaps = tcx.infer_ctxt().with_trait_object_mode(trait_object_mode).enter(|infcx| {
7175
let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
7276
overlap(selcx, impl1_def_id, impl2_def_id).is_some()
7377
});
@@ -79,7 +83,7 @@ where
7983
// In the case where we detect an error, run the check again, but
8084
// this time tracking intercrate ambuiguity causes for better
8185
// diagnostics. (These take time and can lead to false errors.)
82-
tcx.infer_ctxt().enter(|infcx| {
86+
tcx.infer_ctxt().with_trait_object_mode(trait_object_mode).enter(|infcx| {
8387
let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
8488
selcx.enable_tracking_intercrate_ambiguity_causes();
8589
on_overlap(overlap(selcx, impl1_def_id, impl2_def_id).unwrap())

src/librustc/traits/error_reporting.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
459459
{
460460
let simp = fast_reject::simplify_type(self.tcx,
461461
trait_ref.skip_binder().self_ty(),
462-
true);
462+
true,);
463463
let all_impls = self.tcx.all_impls(trait_ref.def_id());
464464

465465
match simp {

src/librustc/traits/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ pub use self::select::{EvaluationCache, SelectionContext, SelectionCache};
6464
pub use self::select::{EvaluationResult, IntercrateAmbiguityCause, OverflowError};
6565
pub use self::specialize::{OverlapError, specialization_graph, translate_substs};
6666
pub use self::specialize::find_associated_item;
67+
pub use self::specialize::specialization_graph::FutureCompatOverlapError;
68+
pub use self::specialize::specialization_graph::FutureCompatOverlapErrorKind;
6769
pub use self::engine::{TraitEngine, TraitEngineExt};
6870
pub use self::util::{elaborate_predicates, elaborate_trait_ref, elaborate_trait_refs};
6971
pub use self::util::{supertraits, supertrait_def_ids, transitive_bounds,

src/librustc/traits/select.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ use infer::{InferCtxt, InferOk, TypeFreshener};
4444
use middle::lang_items;
4545
use mir::interpret::GlobalId;
4646
use ty::fast_reject;
47-
use ty::relate::TypeRelation;
47+
use ty::relate::{TypeRelation, TraitObjectMode};
4848
use ty::subst::{Subst, Substs};
4949
use ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable};
5050

@@ -1501,6 +1501,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
15011501
return false;
15021502
}
15031503

1504+
// Same idea as the above, but for alt trait object modes. These
1505+
// should only be used in intercrate mode - better safe than sorry.
1506+
if self.infcx.trait_object_mode() != TraitObjectMode::NoSquash {
1507+
bug!("using squashing TraitObjectMode outside of intercrate mode? param_env={:?}",
1508+
param_env);
1509+
}
1510+
15041511
// Otherwise, we can use the global cache.
15051512
true
15061513
}
@@ -3699,7 +3706,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
36993706
previous: &ty::PolyTraitRef<'tcx>,
37003707
current: &ty::PolyTraitRef<'tcx>,
37013708
) -> bool {
3702-
let mut matcher = ty::_match::Match::new(self.tcx());
3709+
let mut matcher = ty::_match::Match::new(
3710+
self.tcx(), self.infcx.trait_object_mode());
37033711
matcher.relate(previous, current).is_ok()
37043712
}
37053713

src/librustc/traits/specialize/mod.rs

+14-6
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ pub mod specialization_graph;
2424
use hir::def_id::DefId;
2525
use infer::{InferCtxt, InferOk};
2626
use lint;
27+
use traits::{self, FutureCompatOverlapErrorKind, ObligationCause, TraitEngine};
2728
use rustc_data_structures::fx::FxHashSet;
2829
use rustc_data_structures::sync::Lrc;
2930
use syntax_pos::DUMMY_SP;
30-
use traits::{self, ObligationCause, TraitEngine};
3131
use traits::select::IntercrateAmbiguityCause;
3232
use ty::{self, TyCtxt, TypeFoldable};
3333
use ty::subst::{Subst, Substs};
@@ -36,6 +36,7 @@ use super::{SelectionContext, FulfillmentContext};
3636
use super::util::impl_trait_ref_and_oblig;
3737

3838
/// Information pertinent to an overlapping impl error.
39+
#[derive(Debug)]
3940
pub struct OverlapError {
4041
pub with_impl: DefId,
4142
pub trait_desc: String,
@@ -318,8 +319,9 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
318319
let insert_result = sg.insert(tcx, impl_def_id);
319320
// Report error if there was one.
320321
let (overlap, used_to_be_allowed) = match insert_result {
321-
Err(overlap) => (Some(overlap), false),
322-
Ok(opt_overlap) => (opt_overlap, true)
322+
Err(overlap) => (Some(overlap), None),
323+
Ok(Some(overlap)) => (Some(overlap.error), Some(overlap.kind)),
324+
Ok(None) => (None, None)
323325
};
324326

325327
if let Some(overlap) = overlap {
@@ -329,14 +331,20 @@ pub(super) fn specialization_graph_provider<'a, 'tcx>(
329331
String::new(), |ty| {
330332
format!(" for type `{}`", ty)
331333
}),
332-
if used_to_be_allowed { " (E0119)" } else { "" }
334+
if used_to_be_allowed.is_some() { " (E0119)" } else { "" }
333335
);
334336
let impl_span = tcx.sess.source_map().def_span(
335337
tcx.span_of_impl(impl_def_id).unwrap()
336338
);
337-
let mut err = if used_to_be_allowed {
339+
let mut err = if let Some(kind) = used_to_be_allowed {
340+
let lint = match kind {
341+
FutureCompatOverlapErrorKind::Issue43355 =>
342+
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
343+
FutureCompatOverlapErrorKind::Issue33140 =>
344+
lint::builtin::ORDER_DEPENDENT_TRAIT_OBJECTS,
345+
};
338346
tcx.struct_span_lint_node(
339-
lint::builtin::INCOHERENT_FUNDAMENTAL_IMPLS,
347+
lint,
340348
tcx.hir().as_local_node_id(impl_def_id).unwrap(),
341349
impl_span,
342350
&msg)

0 commit comments

Comments
 (0)