summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_ast_passes/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_ast_passes/src')
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs23
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs42
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs10
3 files changed, 35 insertions, 40 deletions
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index eb9c841d8..902b4b1a1 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -42,7 +42,6 @@ enum SelfSemantic {
/// What is the context that prevents using `~const`?
enum DisallowTildeConstContext<'a> {
TraitObject,
- ImplTrait,
Fn(FnKind<'a>),
}
@@ -187,11 +186,7 @@ impl<'a> AstValidator<'a> {
fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
let old = mem::replace(&mut self.outer_impl_trait, outer);
- if outer.is_some() {
- self.with_banned_tilde_const(DisallowTildeConstContext::ImplTrait, f);
- } else {
- f(self);
- }
+ f(self);
self.outer_impl_trait = old;
}
@@ -1105,16 +1100,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
replace_span: self.ending_semi_or_hi(item.span),
extern_block_suggestion: match sig.header.ext {
Extern::None => None,
- Extern::Implicit(start_span) => Some(ExternBlockSuggestion {
+ Extern::Implicit(start_span) => Some(ExternBlockSuggestion::Implicit {
start_span,
end_span: item.span.shrink_to_hi(),
- abi: None,
- }),
- Extern::Explicit(abi, start_span) => Some(ExternBlockSuggestion {
- start_span,
- end_span: item.span.shrink_to_hi(),
- abi: Some(abi.symbol_unescaped),
}),
+ Extern::Explicit(abi, start_span) => {
+ Some(ExternBlockSuggestion::Explicit {
+ start_span,
+ end_span: item.span.shrink_to_hi(),
+ abi: abi.symbol_unescaped,
+ })
+ }
},
});
}
@@ -1384,7 +1380,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
let mut err = self.err_handler().struct_span_err(bound.span(), "`~const` is not allowed here");
match reason {
DisallowTildeConstContext::TraitObject => err.note("trait objects cannot have `~const` trait bounds"),
- DisallowTildeConstContext::ImplTrait => err.note("`impl Trait`s cannot have `~const` trait bounds"),
DisallowTildeConstContext::Fn(FnKind::Closure(..)) => err.note("closures cannot have `~const` trait bounds"),
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => err.span_note(ident.span, "this function is not `const`, so it cannot have `~const` trait bounds"),
};
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 59f582f10..09e262452 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -1,6 +1,5 @@
//! Errors emitted by ast_passes.
-use rustc_errors::{fluent, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessage};
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};
@@ -207,28 +206,21 @@ pub struct FnWithoutBody {
pub extern_block_suggestion: Option<ExternBlockSuggestion>,
}
-pub struct ExternBlockSuggestion {
- pub start_span: Span,
- pub end_span: Span,
- pub abi: Option<Symbol>,
-}
-
-impl AddToDiagnostic for ExternBlockSuggestion {
- fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
- where
- F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
- {
- let start_suggestion = if let Some(abi) = self.abi {
- format!("extern \"{}\" {{", abi)
- } else {
- "extern {".to_owned()
- };
- let end_suggestion = " }".to_owned();
-
- diag.multipart_suggestion(
- fluent::extern_block_suggestion,
- vec![(self.start_span, start_suggestion), (self.end_span, end_suggestion)],
- Applicability::MaybeIncorrect,
- );
- }
+#[derive(Subdiagnostic)]
+pub enum ExternBlockSuggestion {
+ #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
+ Implicit {
+ #[suggestion_part(code = "extern {{")]
+ start_span: Span,
+ #[suggestion_part(code = " }}")]
+ end_span: Span,
+ },
+ #[multipart_suggestion(ast_passes_extern_block_suggestion, applicability = "maybe-incorrect")]
+ Explicit {
+ #[suggestion_part(code = "extern \"{abi}\" {{")]
+ start_span: Span,
+ #[suggestion_part(code = " }}")]
+ end_span: Span,
+ abi: Symbol,
+ },
}
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 32f45f8b5..89ba6f936 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -385,6 +385,14 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
ast::ExprKind::TryBlock(_) => {
gate_feature_post!(&self, try_blocks, e.span, "`try` expression is experimental");
}
+ ast::ExprKind::Closure(box ast::Closure { constness: ast::Const::Yes(_), .. }) => {
+ gate_feature_post!(
+ &self,
+ const_closures,
+ e.span,
+ "const closures are experimental"
+ );
+ }
_ => {}
}
visit::walk_expr(self, e)
@@ -630,7 +638,7 @@ fn check_incompatible_features(sess: &Session) {
{
let spans = vec![f1_span, f2_span];
sess.struct_span_err(
- spans.clone(),
+ spans,
&format!(
"features `{}` and `{}` are incompatible, using them at the same time \
is not allowed",