about summary refs log tree commit diff
path: root/src/librustc/util
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-01-05 03:36:31 +0000
committerbors <bors@rust-lang.org>2019-01-05 03:36:31 +0000
commit2fba17fc972f89fe9165fbed77d2f0ad6d3e2174 (patch)
tree4d53cc7f637ccfb8c21ea5c1c113907d96694749 /src/librustc/util
parent244b05db12e47efef4695036974bc25fde13b828 (diff)
parentc213b0db2e8e344c419095450dbbdae71afa8c61 (diff)
downloadrust-2fba17fc972f89fe9165fbed77d2f0ad6d3e2174.tar.gz
rust-2fba17fc972f89fe9165fbed77d2f0ad6d3e2174.zip
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
Diffstat (limited to 'src/librustc/util')
-rw-r--r--src/librustc/util/ppaux.rs48
1 files changed, 35 insertions, 13 deletions
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index 37bc9397d90..04e571863d4 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -711,21 +711,43 @@ define_print! {
             ty::tls::with(|tcx| {
                 // Use a type that can't appear in defaults of type parameters.
                 let dummy_self = tcx.mk_infer(ty::FreshTy(0));
-
-                let principal = tcx
-                    .lift(&self.principal())
-                    .expect("could not lift TraitRef for printing")
-                    .with_self_ty(tcx, dummy_self);
-                let projections = self.projection_bounds().map(|p| {
-                    tcx.lift(&p)
-                        .expect("could not lift projection for printing")
-                        .with_self_ty(tcx, dummy_self)
-                }).collect::<Vec<_>>();
-                cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
+                let mut first = true;
+
+                if let Some(principal) = self.principal() {
+                    let principal = tcx
+                        .lift(&principal)
+                        .expect("could not lift TraitRef for printing")
+                        .with_self_ty(tcx, dummy_self);
+                    let projections = self.projection_bounds().map(|p| {
+                        tcx.lift(&p)
+                            .expect("could not lift projection for printing")
+                            .with_self_ty(tcx, dummy_self)
+                    }).collect::<Vec<_>>();
+                    cx.parameterized(f, principal.substs, principal.def_id, &projections)?;
+                    first = false;
+                }
 
                 // Builtin bounds.
-                for did in self.auto_traits() {
-                    write!(f, " + {}", tcx.item_path_str(did))?;
+                let mut auto_traits: Vec<_> = self.auto_traits().map(|did| {
+                    tcx.item_path_str(did)
+                }).collect();
+
+                // The auto traits come ordered by `DefPathHash`. While
+                // `DefPathHash` is *stable* in the sense that it depends on
+                // neither the host nor the phase of the moon, it depends
+                // "pseudorandomly" on the compiler version and the target.
+                //
+                // To avoid that causing instabilities in compiletest
+                // output, sort the auto-traits alphabetically.
+                auto_traits.sort();
+
+                for auto_trait in auto_traits {
+                    if !first {
+                        write!(f, " + ")?;
+                    }
+                    first = false;
+
+                    write!(f, "{}", auto_trait)?;
                 }
 
                 Ok(())