about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-11-23 16:33:03 +0000
committerbors <bors@rust-lang.org>2020-11-23 16:33:03 +0000
commit40624dde6cdfad2576b4d795c97583188a814884 (patch)
tree7994ac92e4e2b85ce96de1512eef29e96bfab33d /compiler
parent40cf72108edb9b8633a9d284b238988309204494 (diff)
parentea3c269b70ea9dd77453ab13b9cfec0f4e1df899 (diff)
Auto merge of #79345 - jonas-schievink:rollup-1yhhzx9, r=jonas-schievink
Rollup of 10 pull requests

Successful merges:

 - #76829 (stabilize const_int_pow)
 - #79080 (MIR visitor: Don't treat debuginfo field access as a use of the struct)
 - #79236 (const_generics: assert resolve hack causes an error)
 - #79287 (Allow using generic trait methods in `const fn`)
 - #79324 (Use Option::and_then instead of open-coding it)
 - #79325 (Reduce boilerplate with the `?` operator)
 - #79330 (Fix typo in comment)
 - #79333 (doc typo)
 - #79337 (Use Option::map instead of open coding it)
 - #79343 (Add my (`@flip1995)` work mail to the mailmap)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_builtin_macros/src/format_foreign.rs16
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs7
-rw-r--r--compiler/rustc_infer/src/traits/util.rs2
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs13
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs9
-rw-r--r--compiler/rustc_middle/src/traits/select.rs2
-rw-r--r--compiler/rustc_middle/src/traits/structural_impls.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs6
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs8
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs5
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/validation.rs40
-rw-r--r--compiler/rustc_mir/src/transform/validate.rs8
-rw-r--r--compiler/rustc_privacy/src/lib.rs2
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs2
-rw-r--r--compiler/rustc_resolve/src/lib.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs26
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs2
-rw-r--r--compiler/rustc_typeck/src/astconv/mod.rs4
-rw-r--r--compiler/rustc_typeck/src/check/demand.rs10
24 files changed, 120 insertions, 80 deletions
diff --git a/compiler/rustc_builtin_macros/src/format_foreign.rs b/compiler/rustc_builtin_macros/src/format_foreign.rs
index b69b00d65f2..f00dfd1241f 100644
--- a/compiler/rustc_builtin_macros/src/format_foreign.rs
+++ b/compiler/rustc_builtin_macros/src/format_foreign.rs
@@ -649,17 +649,13 @@ pub mod shell {
     impl<'a> Iterator for Substitutions<'a> {
         type Item = Substitution<'a>;
         fn next(&mut self) -> Option<Self::Item> {
-            match parse_next_substitution(self.s) {
-                Some((mut sub, tail)) => {
-                    self.s = tail;
-                    if let Some(InnerSpan { start, end }) = sub.position() {
-                        sub.set_position(start + self.pos, end + self.pos);
-                        self.pos += end;
-                    }
-                    Some(sub)
-                }
-                None => None,
+            let (mut sub, tail) = parse_next_substitution(self.s)?;
+            self.s = tail;
+            if let Some(InnerSpan { start, end }) = sub.position() {
+                sub.set_position(start + self.pos, end + self.pos);
+                self.pos += end;
             }
+            Some(sub)
         }
 
         fn size_hint(&self) -> (usize, Option<usize>) {
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 5e8ff14f0aa..96484034da7 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -1152,10 +1152,7 @@ impl<'ll> MemberDescription<'ll> {
                 self.size.bits(),
                 self.align.bits() as u32,
                 self.offset.bits(),
-                match self.discriminant {
-                    None => None,
-                    Some(value) => Some(cx.const_u64(value)),
-                },
+                self.discriminant.map(|v| cx.const_u64(v)),
                 self.flags,
                 self.type_metadata,
             )
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index fd20709f5d8..9651d0505e6 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -37,12 +37,9 @@ impl<'a, 'tcx> TerminatorCodegenHelper<'tcx> {
     /// `funclet_bb` member if it is not `None`.
     fn funclet<'b, Bx: BuilderMethods<'a, 'tcx>>(
         &self,
-        fx: &'b mut FunctionCx<'a, 'tcx, Bx>,
+        fx: &'b FunctionCx<'a, 'tcx, Bx>,
     ) -> Option<&'b Bx::Funclet> {
-        match self.funclet_bb {
-            Some(funcl) => fx.funclets[funcl].as_ref(),
-            None => None,
-        }
+        self.funclet_bb.and_then(|funcl| fx.funclets[funcl].as_ref())
     }
 
     fn lltarget<Bx: BuilderMethods<'a, 'tcx>>(
diff --git a/compiler/rustc_infer/src/traits/util.rs b/compiler/rustc_infer/src/traits/util.rs
index b0b0e4372b8..8273c2d291d 100644
--- a/compiler/rustc_infer/src/traits/util.rs
+++ b/compiler/rustc_infer/src/traits/util.rs
@@ -309,7 +309,7 @@ impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToT
     fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
         while let Some(obligation) = self.base_iterator.next() {
             if let Some(data) = obligation.predicate.to_opt_poly_trait_ref() {
-                return Some(data);
+                return Some(data.value);
             }
         }
         None
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 638dd8ce970..ad47c6e75d3 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -1017,11 +1017,14 @@ macro_rules! visit_place_fns {
             let mut context = context;
 
             if !place.projection.is_empty() {
-                context = if context.is_mutating_use() {
-                    PlaceContext::MutatingUse(MutatingUseContext::Projection)
-                } else {
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
-                };
+                if context.is_use() {
+                    // ^ Only change the context if it is a real use, not a "use" in debuginfo.
+                    context = if context.is_mutating_use() {
+                        PlaceContext::MutatingUse(MutatingUseContext::Projection)
+                    } else {
+                        PlaceContext::NonMutatingUse(NonMutatingUseContext::Projection)
+                    };
+                }
             }
 
             self.visit_local(&place.local, context, location);
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 4deb7225dcb..1902a97e21c 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -16,6 +16,7 @@ use crate::ty::{self, AdtKind, Ty, TyCtxt};
 use rustc_errors::{Applicability, DiagnosticBuilder};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::Constness;
 use rustc_span::symbol::Symbol;
 use rustc_span::{Span, DUMMY_SP};
 use smallvec::SmallVec;
@@ -457,7 +458,7 @@ pub enum ImplSource<'tcx, N> {
     /// for some type parameter. The `Vec<N>` represents the
     /// obligations incurred from normalizing the where-clause (if
     /// any).
-    Param(Vec<N>),
+    Param(Vec<N>, Constness),
 
     /// Virtual calls through an object.
     Object(ImplSourceObjectData<'tcx, N>),
@@ -487,7 +488,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
     pub fn nested_obligations(self) -> Vec<N> {
         match self {
             ImplSource::UserDefined(i) => i.nested,
-            ImplSource::Param(n) => n,
+            ImplSource::Param(n, _) => n,
             ImplSource::Builtin(i) => i.nested,
             ImplSource::AutoImpl(d) => d.nested,
             ImplSource::Closure(c) => c.nested,
@@ -502,7 +503,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
     pub fn borrow_nested_obligations(&self) -> &[N] {
         match &self {
             ImplSource::UserDefined(i) => &i.nested[..],
-            ImplSource::Param(n) => &n[..],
+            ImplSource::Param(n, _) => &n[..],
             ImplSource::Builtin(i) => &i.nested[..],
             ImplSource::AutoImpl(d) => &d.nested[..],
             ImplSource::Closure(c) => &c.nested[..],
@@ -524,7 +525,7 @@ impl<'tcx, N> ImplSource<'tcx, N> {
                 substs: i.substs,
                 nested: i.nested.into_iter().map(f).collect(),
             }),
-            ImplSource::Param(n) => ImplSource::Param(n.into_iter().map(f).collect()),
+            ImplSource::Param(n, ct) => ImplSource::Param(n.into_iter().map(f).collect(), ct),
             ImplSource::Builtin(i) => ImplSource::Builtin(ImplSourceBuiltinData {
                 nested: i.nested.into_iter().map(f).collect(),
             }),
diff --git a/compiler/rustc_middle/src/traits/select.rs b/compiler/rustc_middle/src/traits/select.rs
index c570ad3273d..e056240f941 100644
--- a/compiler/rustc_middle/src/traits/select.rs
+++ b/compiler/rustc_middle/src/traits/select.rs
@@ -101,7 +101,7 @@ pub enum SelectionCandidate<'tcx> {
         /// `false` if there are no *further* obligations.
         has_nested: bool,
     },
-    ParamCandidate(ty::PolyTraitRef<'tcx>),
+    ParamCandidate(ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>),
     ImplCandidate(DefId),
     AutoImplCandidate(DefId),
 
diff --git a/compiler/rustc_middle/src/traits/structural_impls.rs b/compiler/rustc_middle/src/traits/structural_impls.rs
index 194e275496e..5a17d38c734 100644
--- a/compiler/rustc_middle/src/traits/structural_impls.rs
+++ b/compiler/rustc_middle/src/traits/structural_impls.rs
@@ -21,7 +21,9 @@ impl<'tcx, N: fmt::Debug> fmt::Debug for traits::ImplSource<'tcx, N> {
 
             super::ImplSource::Object(ref d) => write!(f, "{:?}", d),
 
-            super::ImplSource::Param(ref n) => write!(f, "ImplSourceParamData({:?})", n),
+            super::ImplSource::Param(ref n, ct) => {
+                write!(f, "ImplSourceParamData({:?}, {:?})", n, ct)
+            }
 
             super::ImplSource::Builtin(ref d) => write!(f, "{:?}", d),
 
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 36cbd36a770..a6f91278a3b 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -42,7 +42,9 @@ use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefPathHash, Definitions};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::lang_items::LangItem;
-use rustc_hir::{HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate};
+use rustc_hir::{
+    Constness, HirId, ItemKind, ItemLocalId, ItemLocalMap, ItemLocalSet, Node, TraitCandidate,
+};
 use rustc_index::vec::{Idx, IndexVec};
 use rustc_macros::HashStable;
 use rustc_session::config::{BorrowckMode, CrateType, OutputFilenames};
@@ -1635,6 +1637,8 @@ nop_list_lift! {projs; ProjectionKind => ProjectionKind}
 // This is the impl for `&'a InternalSubsts<'a>`.
 nop_list_lift! {substs; GenericArg<'a> => GenericArg<'tcx>}
 
+CloneLiftImpls! { for<'tcx> { Constness, } }
+
 pub mod tls {
     use super::{ptr_eq, GlobalCtxt, TyCtxt};
 
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 6a67935cd98..5d8edcf70bf 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1503,9 +1503,11 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
 }
 
 impl<'tcx> Predicate<'tcx> {
-    pub fn to_opt_poly_trait_ref(self) -> Option<PolyTraitRef<'tcx>> {
+    pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
         match self.skip_binders() {
-            PredicateAtom::Trait(t, _) => Some(ty::Binder::bind(t.trait_ref)),
+            PredicateAtom::Trait(t, constness) => {
+                Some(ConstnessAnd { constness, value: ty::Binder::bind(t.trait_ref) })
+            }
             PredicateAtom::Projection(..)
             | PredicateAtom::Subtype(..)
             | PredicateAtom::RegionOutlives(..)
@@ -1947,7 +1949,7 @@ impl<'tcx> ParamEnv<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TypeFoldable)]
 pub struct ConstnessAnd<T> {
     pub constness: Constness,
     pub value: T,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 4bf16436855..c906b8ac901 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1106,10 +1106,7 @@ impl<T> Binder<T> {
 
 impl<T> Binder<Option<T>> {
     pub fn transpose(self) -> Option<Binder<T>> {
-        match self.0 {
-            Some(v) => Some(Binder(v)),
-            None => None,
-        }
+        self.0.map(Binder)
     }
 }
 
diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs
index e4893044a15..d00038f345c 100644
--- a/compiler/rustc_mir/src/transform/check_consts/validation.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs
@@ -4,6 +4,7 @@ use rustc_errors::{struct_span_err, Applicability, Diagnostic, ErrorReported};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, HirId, LangItem};
 use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::cast::CastTy;
@@ -11,9 +12,10 @@ use rustc_middle::ty::subst::GenericArgKind;
 use rustc_middle::ty::{
     self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt, TypeAndMut,
 };
+use rustc_middle::ty::{Binder, TraitPredicate, TraitRef};
 use rustc_span::{sym, Span, Symbol};
 use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
-use rustc_trait_selection::traits::{self, TraitEngine};
+use rustc_trait_selection::traits::{self, SelectionContext, TraitEngine};
 
 use std::mem;
 use std::ops::Deref;
@@ -765,9 +767,39 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
                     }
                 };
 
-                // Resolve a trait method call to its concrete implementation, which may be in a
-                // `const` trait impl.
-                if self.tcx.features().const_trait_impl {
+                // Attempting to call a trait method?
+                if let Some(trait_id) = tcx.trait_of_item(callee) {
+                    if !self.tcx.features().const_trait_impl {
+                        self.check_op(ops::FnCallNonConst(callee));
+                        return;
+                    }
+
+                    let trait_ref = TraitRef::from_method(tcx, trait_id, substs);
+                    let obligation = Obligation::new(
+                        ObligationCause::dummy(),
+                        param_env,
+                        Binder::bind(TraitPredicate {
+                            trait_ref: TraitRef::from_method(tcx, trait_id, substs),
+                        }),
+                    );
+
+                    let implsrc = tcx.infer_ctxt().enter(|infcx| {
+                        let mut selcx = SelectionContext::new(&infcx);
+                        selcx.select(&obligation).unwrap()
+                    });
+
+                    // If the method is provided via a where-clause that does not use the `?const`
+                    // opt-out, the call is allowed.
+                    if let Some(ImplSource::Param(_, hir::Constness::Const)) = implsrc {
+                        debug!(
+                            "const_trait_impl: provided {:?} via where-clause in {:?}",
+                            trait_ref, param_env
+                        );
+                        return;
+                    }
+
+                    // Resolve a trait method call to its concrete implementation, which may be in a
+                    // `const` trait impl.
                     let instance = Instance::resolve(tcx, param_env, callee, substs);
                     debug!("Resolving ({:?}) -> {:?}", callee, instance);
                     if let Ok(Some(func)) = instance {
diff --git a/compiler/rustc_mir/src/transform/validate.rs b/compiler/rustc_mir/src/transform/validate.rs
index 919e4a90a17..29b90bff210 100644
--- a/compiler/rustc_mir/src/transform/validate.rs
+++ b/compiler/rustc_mir/src/transform/validate.rs
@@ -12,7 +12,7 @@ use rustc_middle::mir::traversal;
 use rustc_middle::mir::visit::{PlaceContext, Visitor};
 use rustc_middle::mir::{
     AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, PlaceRef,
-    Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
+    Rvalue, SourceScope, Statement, StatementKind, Terminator, TerminatorKind,
 };
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeFoldable};
@@ -200,12 +200,6 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
         }
     }
 
-    fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) {
-        // Debuginfo can contain field projections, which count as a use of the base local. Skip
-        // debuginfo so that we avoid the storage liveness assertion in that case.
-        self.visit_source_info(&var_debug_info.source_info);
-    }
-
     fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
         // This check is somewhat expensive, so only run it when -Zvalidate-mir is passed.
         if self.tcx.sess.opts.debugging_opts.validate_mir {
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 4a0d356d337..b8fa9081aa3 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -691,7 +691,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
             hir::ItemKind::GlobalAsm(..) => {}
             hir::ItemKind::OpaqueTy(..) => {
                 // HACK(jynelson): trying to infer the type of `impl trait` breaks `async-std` (and `pub async fn` in general)
-                // Since rustdoc never need to do codegen and doesn't care about link-time reachability,
+                // Since rustdoc never needs to do codegen and doesn't care about link-time reachability,
                 // mark this as unreachable.
                 // See https://github.com/rust-lang/rust/issues/75100
                 if !self.tcx.sess.opts.actually_rustdoc {
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 2cca1a6ee59..67491b5bf7e 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -143,7 +143,7 @@ impl<'a> Resolver<'a> {
                     _ => {
                         bug!(
                             "GenericParamsFromOuterFunction should only be used with Res::SelfTy, \
-                            DefKind::TyParam"
+                            DefKind::TyParam or DefKind::ConstParam"
                         );
                     }
                 }
diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs
index d18335ef2e6..e8a06265ada 100644
--- a/compiler/rustc_resolve/src/lib.rs
+++ b/compiler/rustc_resolve/src/lib.rs
@@ -2539,6 +2539,7 @@ impl<'a> Resolver<'a> {
         span: Span,
         all_ribs: &[Rib<'a>],
     ) -> Res {
+        const CG_BUG_STR: &str = "min_const_generics resolve check didn't stop compilation";
         debug!("validate_res_from_ribs({:?})", res);
         let ribs = &all_ribs[rib_index + 1..];
 
@@ -2639,6 +2640,8 @@ impl<'a> Resolver<'a> {
                                             },
                                         );
                                     }
+
+                                    self.session.delay_span_bug(span, CG_BUG_STR);
                                     return Res::Err;
                                 }
                             }
@@ -2720,6 +2723,8 @@ impl<'a> Resolver<'a> {
                                         },
                                     );
                                 }
+
+                                self.session.delay_span_bug(span, CG_BUG_STR);
                                 return Res::Err;
                             }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index d2556c44fb4..ca3369b8f1e 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -350,11 +350,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
         // Micro-optimization: filter out predicates relating to different traits.
         let matching_bounds =
-            all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());
+            all_bounds.filter(|p| p.value.def_id() == stack.obligation.predicate.def_id());
 
         // Keep only those bounds which may apply, and propagate overflow if it occurs.
         for bound in matching_bounds {
-            let wc = self.evaluate_where_clause(stack, bound)?;
+            let wc = self.evaluate_where_clause(stack, bound.value)?;
             if wc.may_apply() {
                 candidates.vec.push(ParamCandidate(bound));
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index 7c155c7684e..a42c8021346 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -8,6 +8,7 @@
 //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::lang_items::LangItem;
+use rustc_hir::Constness;
 use rustc_index::bit_set::GrowableBitSet;
 use rustc_infer::infer::InferOk;
 use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
@@ -55,8 +56,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             }
 
             ParamCandidate(param) => {
-                let obligations = self.confirm_param_candidate(obligation, param);
-                Ok(ImplSource::Param(obligations))
+                let obligations = self.confirm_param_candidate(obligation, param.value);
+                Ok(ImplSource::Param(obligations, param.constness))
             }
 
             ImplCandidate(impl_def_id) => {
@@ -70,7 +71,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
             ProjectionCandidate(idx) => {
                 let obligations = self.confirm_projection_candidate(obligation, idx)?;
-                Ok(ImplSource::Param(obligations))
+                // FIXME(jschievink): constness
+                Ok(ImplSource::Param(obligations, Constness::NotConst))
             }
 
             ObjectCandidate(idx) => {
@@ -106,7 +108,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 // This indicates something like `Trait + Send: Send`. In this case, we know that
                 // this holds because that's what the object type is telling us, and there's really
                 // no additional obligations to prove and no types in particular to unify, etc.
-                Ok(ImplSource::Param(Vec::new()))
+                Ok(ImplSource::Param(Vec::new(), Constness::NotConst))
             }
 
             BuiltinUnsizeCandidate => {
@@ -151,7 +153,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             obligations.extend(self.infcx.commit_if_ok(|_| {
                 self.infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .sup(placeholder_trait_predicate.trait_ref.to_poly_trait_ref(), candidate)
+                    .sup(placeholder_trait_predicate.trait_ref.to_poly_trait_ref(), candidate.value)
                     .map(|InferOk { obligations, .. }| obligations)
                     .map_err(|_| Unimplemented)
             })?);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 05ff9a6fb9c..5b31998b7d3 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -31,6 +31,7 @@ use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_errors::ErrorReported;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
+use rustc_hir::Constness;
 use rustc_middle::dep_graph::{DepKind, DepNodeIndex};
 use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::fast_reject;
@@ -1335,7 +1336,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             (BuiltinCandidate { has_nested: false } | DiscriminantKindCandidate, _) => true,
             (_, BuiltinCandidate { has_nested: false } | DiscriminantKindCandidate) => false,
 
-            (ParamCandidate(..), ParamCandidate(..)) => false,
+            (ParamCandidate(other), ParamCandidate(victim)) => {
+                if other.value == victim.value && victim.constness == Constness::NotConst {
+                    // Drop otherwise equivalent non-const candidates in favor of const candidates.
+                    true
+                } else {
+                    false
+                }
+            }
 
             // Global bounds from the where clause should be ignored
             // here (see issue #50825). Otherwise, we have a where
@@ -1354,11 +1362,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | TraitAliasCandidate(..)
                 | ObjectCandidate(_)
                 | ProjectionCandidate(_),
-            ) => !is_global(cand),
+            ) => !is_global(&cand.value),
             (ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => {
                 // Prefer these to a global where-clause bound
                 // (see issue #50825).
-                is_global(cand)
+                is_global(&cand.value)
             }
             (
                 ImplCandidate(_)
@@ -1373,7 +1381,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             ) => {
                 // Prefer these to a global where-clause bound
                 // (see issue #50825).
-                is_global(cand) && other.evaluation.must_apply_modulo_regions()
+                is_global(&cand.value) && other.evaluation.must_apply_modulo_regions()
             }
 
             (ProjectionCandidate(i), ProjectionCandidate(j))
@@ -2364,13 +2372,9 @@ impl<'o, 'tcx> Iterator for TraitObligationStackList<'o, 'tcx> {
     type Item = &'o TraitObligationStack<'o, 'tcx>;
 
     fn next(&mut self) -> Option<&'o TraitObligationStack<'o, 'tcx>> {
-        match self.head {
-            Some(o) => {
-                *self = o.previous;
-                Some(o)
-            }
-            None => None,
-        }
+        let o = self.head?;
+        *self = o.previous;
+        Some(o)
     }
 }
 
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 512591960f5..0133a961c11 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -498,8 +498,8 @@ fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Option<String>
 
     for (p, _) in predicates {
         if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
-            if Some(poly_trait_ref.def_id()) == sized_trait {
-                types_without_default_bounds.remove(poly_trait_ref.self_ty().skip_binder());
+            if Some(poly_trait_ref.value.def_id()) == sized_trait {
+                types_without_default_bounds.remove(poly_trait_ref.value.self_ty().skip_binder());
                 continue;
             }
         }
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 2430620323f..ab4a81c7d15 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -125,7 +125,7 @@ impl<'tcx> TraitAliasExpander<'tcx> {
         let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
             pred.subst_supertrait(tcx, &trait_ref)
                 .to_opt_poly_trait_ref()
-                .map(|trait_ref| item.clone_and_push(trait_ref, *span))
+                .map(|trait_ref| item.clone_and_push(trait_ref.value, *span))
         });
         debug!("expand_trait_aliases: items={:?}", items.clone());
 
@@ -182,7 +182,7 @@ impl Iterator for SupertraitDefIds<'tcx> {
                 .predicates
                 .iter()
                 .filter_map(|(pred, _)| pred.to_opt_poly_trait_ref())
-                .map(|trait_ref| trait_ref.def_id())
+                .map(|trait_ref| trait_ref.value.def_id())
                 .filter(|&super_def_id| visited.insert(super_def_id)),
         );
         Some(def_id)
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index e5a792f229d..5bcb16d21e0 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -294,7 +294,7 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
             let mut cause = cause.clone();
             if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_ref() {
                 let derived_cause = traits::DerivedObligationCause {
-                    parent_trait_ref,
+                    parent_trait_ref: parent_trait_ref.value,
                     parent_code: Rc::new(obligation.cause.code.clone()),
                 };
                 cause.make_mut().code =
diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs
index 89c5adfa14c..b011e26d64b 100644
--- a/compiler/rustc_typeck/src/astconv/mod.rs
+++ b/compiler/rustc_typeck/src/astconv/mod.rs
@@ -1364,7 +1364,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             || {
                 traits::transitive_bounds(
                     tcx,
-                    predicates.iter().filter_map(|(p, _)| p.to_opt_poly_trait_ref()),
+                    predicates.iter().filter_map(|(p, _)| {
+                        p.to_opt_poly_trait_ref().map(|trait_ref| trait_ref.value)
+                    }),
                 )
             },
             || param_name.to_string(),
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 241803fab1e..d12d2cb59a5 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -810,10 +810,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // can be given the suggestion "u32::from(x) > y" rather than
                 // "x > y.try_into().unwrap()".
                 let lhs_expr_and_src = expected_ty_expr.and_then(|expr| {
-                    match self.tcx.sess.source_map().span_to_snippet(expr.span).ok() {
-                        Some(src) => Some((expr, src)),
-                        None => None,
-                    }
+                    self.tcx
+                        .sess
+                        .source_map()
+                        .span_to_snippet(expr.span)
+                        .ok()
+                        .map(|src| (expr, src))
                 });
                 let (span, msg, suggestion) = if let (Some((lhs_expr, lhs_src)), false) =
                     (lhs_expr_and_src, exp_to_found_is_fallible)