Parse ?const ?Trait
This commit is contained in:
parent
3b1a9d35c8
commit
0ac4ba0eed
@ -1254,7 +1254,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
| 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 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -917,11 +917,20 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -27,17 +27,13 @@ struct BoundModifiers {
|
||||
}
|
||||
|
||||
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 @@ impl<'a> Parser<'a> {
|
||||
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))
|
||||
}
|
||||
|
@ -279,6 +279,11 @@ pub enum TraitBoundModifier {
|
||||
|
||||
/// `?const Trait`
|
||||
MaybeConst,
|
||||
|
||||
/// `?const ?Trait`
|
||||
//
|
||||
// This parses but will be rejected during AST validation.
|
||||
MaybeConstMaybe,
|
||||
}
|
||||
|
||||
/// The AST represents all type param bounds as types.
|
||||
|
Loading…
x
Reference in New Issue
Block a user