Parse `?const ?Trait`
diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs
index 90560c3..bc922fa 100644
--- a/src/librustc_ast_lowering/lib.rs
+++ b/src/librustc_ast_lowering/lib.rs
@@ -1254,7 +1254,10 @@
                                 | GenericBound::Trait(ref ty, TraitBoundModifier::MaybeConst) => {
                                     Some(this.lower_poly_trait_ref(ty, itctx.reborrow()))
                                 }
-                                GenericBound::Trait(_, TraitBoundModifier::Maybe) => None,
+                                GenericBound::Trait(_, TraitBoundModifier::Maybe)
+                                | GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
+                                    None
+                                }
                                 GenericBound::Outlives(ref lifetime) => {
                                     if lifetime_bound.is_none() {
                                         lifetime_bound = Some(this.lower_lifetime(lifetime));
@@ -2297,8 +2300,10 @@
     fn lower_trait_bound_modifier(&mut self, f: TraitBoundModifier) -> hir::TraitBoundModifier {
         match f {
             TraitBoundModifier::None => hir::TraitBoundModifier::None,
-            TraitBoundModifier::Maybe => hir::TraitBoundModifier::Maybe,
             TraitBoundModifier::MaybeConst => hir::TraitBoundModifier::MaybeConst,
+            TraitBoundModifier::MaybeConstMaybe | TraitBoundModifier::Maybe => {
+                hir::TraitBoundModifier::Maybe
+            }
         }
     }
 
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index 23cb973..9b71704 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -917,11 +917,20 @@
     }
 
     fn visit_param_bound(&mut self, bound: &'a GenericBound) {
-        if let GenericBound::Trait(_, TraitBoundModifier::MaybeConst) = bound {
-            if let Some(ctx) = self.bound_context {
-                let msg = format!("`?const` is not permitted in {}", ctx.description());
-                self.err_handler().span_err(bound.span(), &msg);
+        match bound {
+            GenericBound::Trait(_, TraitBoundModifier::MaybeConst) => {
+                if let Some(ctx) = self.bound_context {
+                    let msg = format!("`?const` is not permitted in {}", ctx.description());
+                    self.err_handler().span_err(bound.span(), &msg);
+                }
             }
+
+            GenericBound::Trait(_, TraitBoundModifier::MaybeConstMaybe) => {
+                self.err_handler()
+                    .span_err(bound.span(), "`?const` and `?` are mutually exclusive");
+            }
+
+            _ => {}
         }
 
         visit::walk_param_bound(self, bound)
diff --git a/src/librustc_parse/parser/ty.rs b/src/librustc_parse/parser/ty.rs
index 9c91807..efd8acc 100644
--- a/src/librustc_parse/parser/ty.rs
+++ b/src/librustc_parse/parser/ty.rs
@@ -27,17 +27,13 @@
 }
 
 impl BoundModifiers {
-    fn to_trait_bound_modifier(&self) -> Result<TraitBoundModifier, &'static str> {
-        let modifier = match (self.maybe, self.maybe_const) {
+    fn to_trait_bound_modifier(&self) -> TraitBoundModifier {
+        match (self.maybe, self.maybe_const) {
             (None, None) => TraitBoundModifier::None,
             (Some(_), None) => TraitBoundModifier::Maybe,
             (None, Some(_)) => TraitBoundModifier::MaybeConst,
-            (Some(_), Some(_)) => {
-                return Err("`?const` and `?` are mutually exclusive");
-            }
-        };
-
-        Ok(modifier)
+            (Some(_), Some(_)) => TraitBoundModifier::MaybeConstMaybe,
+        }
     }
 }
 
@@ -563,16 +559,7 @@
             self.expect(&token::CloseDelim(token::Paren))?;
         }
 
-        let modifier = match modifiers.to_trait_bound_modifier() {
-            Ok(m) => m,
-            Err(msg) => {
-                self.struct_span_err(lo.to(self.prev_span), msg).emit();
-
-                // Continue compilation as if the user had written `?Trait`.
-                TraitBoundModifier::Maybe
-            }
-        };
-
+        let modifier = modifiers.to_trait_bound_modifier();
         let poly_trait = PolyTraitRef::new(lifetime_defs, path, lo.to(self.prev_span));
         Ok(GenericBound::Trait(poly_trait, modifier))
     }
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 88bfb8c..5f38ac4 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -279,6 +279,11 @@
 
     /// `?const Trait`
     MaybeConst,
+
+    /// `?const ?Trait`
+    //
+    // This parses but will be rejected during AST validation.
+    MaybeConstMaybe,
 }
 
 /// The AST represents all type param bounds as types.