"rustc_metadata",
"rustc_mir",
"rustc_parse",
- "rustc_plugin",
"rustc_plugin_impl",
"rustc_resolve",
"rustc_save_analysis",
"syntax_pos",
]
-[[package]]
-name = "rustc_plugin"
-version = "0.0.0"
-dependencies = [
- "rustc_plugin_impl",
-]
-
[[package]]
name = "rustc_plugin_impl"
version = "0.0.0"
"for every macro invocation, print its name and arguments"),
debug_macros: bool = (false, parse_bool, [TRACKED],
"emit line numbers debug info inside macros"),
+ generate_arange_section: bool = (true, parse_bool, [TRACKED],
+ "generate DWARF address ranges for faster lookups"),
keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
"don't clear the hygiene data after analysis"),
keep_ast: bool = (false, parse_bool, [UNTRACKED],
if sess.opts.debugging_opts.disable_instrumentation_preinliner {
add("-disable-preinline");
}
+ if sess.opts.debugging_opts.generate_arange_section {
+ add("-generate-arange-section");
+ }
if get_major_version() >= 8 {
match sess.opts.debugging_opts.merge_functions
.unwrap_or(sess.target.target.options.merge_functions) {
rustc_metadata = { path = "../librustc_metadata" }
rustc_mir = { path = "../librustc_mir" }
rustc_parse = { path = "../librustc_parse" }
-rustc_plugin = { path = "../librustc_plugin/deprecated" } # To get this in the sysroot
-rustc_plugin_impl = { path = "../librustc_plugin" }
+rustc_plugin_impl = { path = "../librustc_plugin_impl" }
rustc_save_analysis = { path = "../librustc_save_analysis" }
rustc_codegen_utils = { path = "../librustc_codegen_utils" }
rustc_error_codes = { path = "../librustc_error_codes" }
const ICE_REPORT_COMPILER_FLAGS_STRIP_VALUE: &[&str] = &["incremental"];
-pub fn source_name(input: &Input) -> FileName {
- match *input {
- Input::File(ref ifile) => ifile.clone().into(),
- Input::Str { ref name, .. } => name.clone(),
- }
-}
-
pub fn abort_on_err<T>(result: Result<T, ErrorReported>, sess: &Session) -> T {
match result {
Err(..) => {
pub use self::PpMode::*;
use crate::abort_on_err;
-use crate::source_name;
-
-
-
// This slightly awkward construction is to allow for each PpMode to
// choose whether it needs to do analyses (which can consume the
// Session) and then pass through the session (now attached to the
}
fn get_source(input: &Input, sess: &Session) -> (String, FileName) {
- let src_name = source_name(input);
+ let src_name = input.source_name();
let src = String::clone(&sess.source_map()
.get_source_file(&src_name)
.unwrap()
E0701: include_str!("./error_codes/E0701.md"),
E0704: include_str!("./error_codes/E0704.md"),
E0705: include_str!("./error_codes/E0705.md"),
+E0706: include_str!("./error_codes/E0706.md"),
E0712: include_str!("./error_codes/E0712.md"),
E0713: include_str!("./error_codes/E0713.md"),
E0714: include_str!("./error_codes/E0714.md"),
E0696, // `continue` pointing to a labeled block
// E0702, // replaced with a generic attribute input check
E0703, // invalid ABI
- E0706, // `async fn` in trait
// E0707, // multiple elided lifetimes used in arguments of `async fn`
E0708, // `async` non-`move` closures with parameters are not currently
// supported
--- /dev/null
+ `async fn`s are not yet supported in traits in Rust.
+
+Erroneous code example:
+
+```compile_fail,edition2018
+trait T {
+ // Neither case is currently supported.
+ async fn foo() {}
+ async fn bar(&self) {}
+}
+```
+
+`async fn`s return an `impl Future`, making the following two examples equivalent:
+
+```edition2018,ignore (example-of-desugaring-equivalence)
+async fn foo() -> User {
+ unimplemented!()
+}
+// The async fn above gets desugared as follows:
+fn foo(&self) -> impl Future<Output = User> + '_ {
+ unimplemented!()
+}
+```
+
+But when it comes to supporting this in traits, there are [a few implementation
+issues][async-is-hard]. One of them is returning `impl Trait` in traits is not supported,
+as it would require [Generic Associated Types] to be supported:
+
+```edition2018,ignore (example-of-desugaring-equivalence)
+impl MyDatabase {
+ async fn get_user(&self) -> User {
+ unimplemented!()
+ }
+}
+
+impl MyDatabase {
+ fn get_user(&self) -> impl Future<Output = User> + '_ {
+ unimplemented!()
+ }
+}
+```
+
+Until these issues are resolved, you can use the [`async-trait` crate], allowing you to use
+`async fn` in traits by desugaring to "boxed futures"
+(`Pin<Box<dyn Future + Send + 'async>>`).
+
+Note that using these trait methods will result in a heap allocation per-function-call. This is not
+a significant cost for the vast majority of applications, but should be considered when deciding
+whether to use this functionality in the public API of a low-level function that is expected to be
+called millions of times a second.
+
+You might be interested in visiting the [async book] for further information.
+
+[`async-trait` crate]: https://crates.io/crates/async-trait
+[async-is-hard]: https://smallcultfollowing.com/babysteps/blog/2019/10/26/async-fn-in-traits-are-hard/
+[Generic Associated Types]: https://github.com/rust-lang/rust/issues/44265
+[async book]: https://rust-lang.github.io/async-book/07_workarounds/06_async_in_traits.html
rustc_typeck = { path = "../librustc_typeck" }
rustc_lint = { path = "../librustc_lint" }
rustc_errors = { path = "../librustc_errors" }
-rustc_plugin = { path = "../librustc_plugin", package = "rustc_plugin_impl" }
+rustc_plugin_impl = { path = "../librustc_plugin_impl" }
rustc_privacy = { path = "../librustc_privacy" }
rustc_resolve = { path = "../librustc_resolve" }
tempfile = "3.0.5"
use rustc_mir as mir;
use rustc_parse::{parse_crate_from_file, parse_crate_from_source_str};
use rustc_passes::{self, ast_validation, hir_stats, layout_test};
-use rustc_plugin as plugin;
-use rustc_plugin::registry::Registry;
+use rustc_plugin_impl as plugin;
+use rustc_plugin_impl::registry::Registry;
use rustc_privacy;
use rustc_resolve::{Resolver, ResolverArenas};
use rustc_traits;
/// anything special (because we know none of the integers are actually wildcards: i.e., we
/// can't span wildcards using ranges).
use self::Constructor::*;
+use self::SliceKind::*;
use self::Usefulness::*;
use self::WitnessPreference::*;
}
}
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+enum SliceKind {
+ /// Patterns of length `n` (`[x, y]`).
+ FixedLen(u64),
+ /// Patterns using the `..` notation (`[x, .., y]`). Captures any array constructor of `length
+ /// >= i + j`. In the case where `array_len` is `Some(_)`, this indicates that we only care
+ /// about the first `i` and the last `j` values of the array, and everything in between is a
+ /// wildcard `_`.
+ VarLen(u64, u64),
+}
+
+impl SliceKind {
+ fn arity(self) -> u64 {
+ match self {
+ FixedLen(length) => length,
+ VarLen(prefix, suffix) => prefix + suffix,
+ }
+ }
+
+ /// Whether this pattern includes patterns of length `other_len`.
+ fn covers_length(self, other_len: u64) -> bool {
+ match self {
+ FixedLen(len) => len == other_len,
+ VarLen(prefix, suffix) => prefix + suffix <= other_len,
+ }
+ }
+
+ /// Returns a collection of slices that spans the values covered by `self`, subtracted by the
+ /// values covered by `other`: i.e., `self \ other` (in set notation).
+ fn subtract(self, other: Self) -> SmallVec<[Self; 1]> {
+ // Remember, `VarLen(i, j)` covers the union of `FixedLen` from `i + j` to infinity.
+ // Naming: we remove the "neg" constructors from the "pos" ones.
+ match self {
+ FixedLen(pos_len) => {
+ if other.covers_length(pos_len) {
+ smallvec![]
+ } else {
+ smallvec![self]
+ }
+ }
+ VarLen(pos_prefix, pos_suffix) => {
+ let pos_len = pos_prefix + pos_suffix;
+ match other {
+ FixedLen(neg_len) => {
+ if neg_len < pos_len {
+ smallvec![self]
+ } else {
+ (pos_len..neg_len)
+ .map(FixedLen)
+ // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
+ .chain(Some(VarLen(neg_len + 1 - pos_suffix, pos_suffix)))
+ .collect()
+ }
+ }
+ VarLen(neg_prefix, neg_suffix) => {
+ let neg_len = neg_prefix + neg_suffix;
+ if neg_len <= pos_len {
+ smallvec![]
+ } else {
+ (pos_len..neg_len).map(FixedLen).collect()
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+/// A constructor for array and slice patterns.
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+struct Slice {
+ /// `None` if the matched value is a slice, `Some(n)` if it is an array of size `n`.
+ array_len: Option<u64>,
+ /// The kind of pattern it is: fixed-length `[x, y]` or variable length `[x, .., y]`.
+ kind: SliceKind,
+}
+
+impl Slice {
+ /// Returns what patterns this constructor covers: either fixed-length patterns or
+ /// variable-length patterns.
+ fn pattern_kind(self) -> SliceKind {
+ match self {
+ Slice { array_len: Some(len), kind: VarLen(prefix, suffix) }
+ if prefix + suffix == len =>
+ {
+ FixedLen(len)
+ }
+ _ => self.kind,
+ }
+ }
+
+ /// Returns what values this constructor covers: either values of only one given length, or
+ /// values of length above a given length.
+ /// This is different from `pattern_kind()` because in some cases the pattern only takes into
+ /// account a subset of the entries of the array, but still only captures values of a given
+ /// length.
+ fn value_kind(self) -> SliceKind {
+ match self {
+ Slice { array_len: Some(len), kind: VarLen(_, _) } => FixedLen(len),
+ _ => self.kind,
+ }
+ }
+
+ fn arity(self) -> u64 {
+ self.pattern_kind().arity()
+ }
+}
+
#[derive(Clone, Debug, PartialEq)]
enum Constructor<'tcx> {
/// The constructor of all patterns that don't vary by constructor,
IntRange(IntRange<'tcx>),
/// Ranges of floating-point literal values (`2.0..=5.2`).
FloatRange(&'tcx ty::Const<'tcx>, &'tcx ty::Const<'tcx>, RangeEnd),
- /// Array patterns of length `n`.
- FixedLenSlice(u64),
- /// Slice patterns. Captures any array constructor of `length >= i + j`.
- VarLenSlice(u64, u64),
+ /// Array and slice patterns.
+ Slice(Slice),
/// Fake extra constructor for enums that aren't allowed to be matched exhaustively.
NonExhaustive,
}
impl<'tcx> Constructor<'tcx> {
fn is_slice(&self) -> bool {
match self {
- FixedLenSlice { .. } | VarLenSlice { .. } => true,
+ Slice(_) => true,
_ => false,
}
}
Single | Variant(_) | ConstantValue(..) | FloatRange(..) => {
if other_ctors.iter().any(|c| c == self) { vec![] } else { vec![self.clone()] }
}
- &FixedLenSlice(self_len) => {
- let overlaps = |c: &Constructor<'_>| match *c {
- FixedLenSlice(other_len) => other_len == self_len,
- VarLenSlice(prefix, suffix) => prefix + suffix <= self_len,
- _ => false,
- };
- if other_ctors.iter().any(overlaps) { vec![] } else { vec![self.clone()] }
- }
- VarLenSlice(..) => {
- let mut remaining_ctors = vec![self.clone()];
-
- // For each used ctor, subtract from the current set of constructors.
- // Naming: we remove the "neg" constructors from the "pos" ones.
- // Remember, `VarLenSlice(i, j)` covers the union of `FixedLenSlice` from
- // `i + j` to infinity.
- for neg_ctor in other_ctors {
- remaining_ctors = remaining_ctors
- .into_iter()
- .flat_map(|pos_ctor| -> SmallVec<[Constructor<'tcx>; 1]> {
- // Compute `pos_ctor \ neg_ctor`.
- match (&pos_ctor, neg_ctor) {
- (&FixedLenSlice(pos_len), &VarLenSlice(neg_prefix, neg_suffix)) => {
- let neg_len = neg_prefix + neg_suffix;
- if neg_len <= pos_len {
- smallvec![]
- } else {
- smallvec![pos_ctor]
- }
- }
- (
- &VarLenSlice(pos_prefix, pos_suffix),
- &VarLenSlice(neg_prefix, neg_suffix),
- ) => {
- let neg_len = neg_prefix + neg_suffix;
- let pos_len = pos_prefix + pos_suffix;
- if neg_len <= pos_len {
- smallvec![]
- } else {
- (pos_len..neg_len).map(FixedLenSlice).collect()
- }
- }
- (&VarLenSlice(pos_prefix, pos_suffix), &FixedLenSlice(neg_len)) => {
- let pos_len = pos_prefix + pos_suffix;
- if neg_len < pos_len {
- smallvec![pos_ctor]
- } else {
- (pos_len..neg_len)
- .map(FixedLenSlice)
- // We know that `neg_len + 1 >= pos_len >= pos_suffix`.
- .chain(Some(VarLenSlice(
- neg_len + 1 - pos_suffix,
- pos_suffix,
- )))
- .collect()
- }
- }
- _ if pos_ctor == *neg_ctor => smallvec![],
- _ => smallvec![pos_ctor],
+ &Slice(slice) => {
+ let mut other_slices = other_ctors
+ .iter()
+ .filter_map(|c: &Constructor<'_>| match c {
+ Slice(slice) => Some(*slice),
+ // FIXME(#65413): We ignore `ConstantValue`s here.
+ ConstantValue(..) => None,
+ _ => bug!("bad slice pattern constructor {:?}", c),
+ })
+ .map(Slice::value_kind);
+
+ match slice.value_kind() {
+ FixedLen(self_len) => {
+ if other_slices.any(|other_slice| other_slice.covers_length(self_len)) {
+ vec![]
+ } else {
+ vec![Slice(slice)]
+ }
+ }
+ kind @ VarLen(..) => {
+ let mut remaining_slices = vec![kind];
+
+ // For each used slice, subtract from the current set of slices.
+ for other_slice in other_slices {
+ remaining_slices = remaining_slices
+ .into_iter()
+ .flat_map(|remaining_slice| remaining_slice.subtract(other_slice))
+ .collect();
+
+ // If the constructors that have been considered so far already cover
+ // the entire range of `self`, no need to look at more constructors.
+ if remaining_slices.is_empty() {
+ break;
}
- })
- .collect();
+ }
- // If the constructors that have been considered so far already cover
- // the entire range of `self`, no need to look at more constructors.
- if remaining_ctors.is_empty() {
- break;
+ remaining_slices
+ .into_iter()
+ .map(|kind| Slice { array_len: slice.array_len, kind })
+ .map(Slice)
+ .collect()
}
}
-
- remaining_ctors
}
IntRange(self_range) => {
let mut remaining_ranges = vec![self_range.clone()];
}
_ => vec![],
},
- FixedLenSlice(_) | VarLenSlice(..) => match ty.kind {
+ Slice(_) => match ty.kind {
ty::Slice(ty) | ty::Array(ty, _) => {
let arity = self.arity(cx, ty);
(0..arity).map(|_| Pat::wildcard_from_ty(ty)).collect()
}
_ => 0,
},
- FixedLenSlice(length) => *length,
- VarLenSlice(prefix, suffix) => prefix + suffix,
+ Slice(slice) => slice.arity(),
ConstantValue(..) | FloatRange(..) | IntRange(..) | NonExhaustive => 0,
}
}
ty::Slice(_) | ty::Array(..) => bug!("bad slice pattern {:?} {:?}", self, ty),
_ => PatKind::Wild,
},
- FixedLenSlice(_) => {
- PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
- }
- &VarLenSlice(prefix_len, _) => {
- let prefix = subpatterns.by_ref().take(prefix_len as usize).collect();
- let suffix = subpatterns.collect();
- let wild = Pat::wildcard_from_ty(ty);
- PatKind::Slice { prefix, slice: Some(wild), suffix }
- }
+ Slice(slice) => match slice.pattern_kind() {
+ FixedLen(_) => {
+ PatKind::Slice { prefix: subpatterns.collect(), slice: None, suffix: vec![] }
+ }
+ VarLen(prefix, _) => {
+ let mut prefix: Vec<_> = subpatterns.by_ref().take(prefix as usize).collect();
+ if slice.array_len.is_some() {
+ // Improves diagnostics a bit: if the type is a known-size array, instead
+ // of reporting `[x, _, .., _, y]`, we prefer to report `[x, .., y]`.
+ // This is incorrect if the size is not known, since `[_, ..]` captures
+ // arrays of lengths `>= 1` whereas `[..]` captures any length.
+ while !prefix.is_empty() && prefix.last().unwrap().is_wildcard() {
+ prefix.pop();
+ }
+ }
+ let suffix: Vec<_> = if slice.array_len.is_some() {
+ // Same as above.
+ subpatterns.skip_while(Pat::is_wildcard).collect()
+ } else {
+ subpatterns.collect()
+ };
+ let wild = Pat::wildcard_from_ty(ty);
+ PatKind::Slice { prefix, slice: Some(wild), suffix }
+ }
+ },
&ConstantValue(value) => PatKind::Constant { value },
&FloatRange(lo, hi, end) => PatKind::Range(PatRange { lo, hi, end }),
IntRange(range) => return range.to_pat(cx.tcx),
}
ty::Array(ref sub_ty, len) if len.try_eval_usize(cx.tcx, cx.param_env).is_some() => {
let len = len.eval_usize(cx.tcx, cx.param_env);
- if len != 0 && cx.is_uninhabited(sub_ty) { vec![] } else { vec![FixedLenSlice(len)] }
+ if len != 0 && cx.is_uninhabited(sub_ty) {
+ vec![]
+ } else {
+ vec![Slice(Slice { array_len: Some(len), kind: VarLen(0, 0) })]
+ }
}
// Treat arrays of a constant but unknown length like slices.
ty::Array(ref sub_ty, _) | ty::Slice(ref sub_ty) => {
- if cx.is_uninhabited(sub_ty) {
- vec![FixedLenSlice(0)]
- } else {
- vec![VarLenSlice(0, 0)]
- }
+ let kind = if cx.is_uninhabited(sub_ty) { FixedLen(0) } else { VarLen(0, 0) };
+ vec![Slice(Slice { array_len: None, kind })]
}
ty::Adt(def, substs) if def.is_enum() => {
let ctors: Vec<_> = def
Some(FloatRange(lo, hi, end))
}
}
- PatKind::Array { .. } => match pat.ty.kind {
- ty::Array(_, length) => Some(FixedLenSlice(length.eval_usize(tcx, param_env))),
- _ => span_bug!(pat.span, "bad ty {:?} for array pattern", pat.ty),
- },
- PatKind::Slice { ref prefix, ref slice, ref suffix } => {
+ PatKind::Array { ref prefix, ref slice, ref suffix }
+ | PatKind::Slice { ref prefix, ref slice, ref suffix } => {
+ let array_len = match pat.ty.kind {
+ ty::Array(_, length) => Some(length.eval_usize(tcx, param_env)),
+ ty::Slice(_) => None,
+ _ => span_bug!(pat.span, "bad ty {:?} for slice pattern", pat.ty),
+ };
let prefix = prefix.len() as u64;
let suffix = suffix.len() as u64;
- if slice.is_some() {
- Some(VarLenSlice(prefix, suffix))
- } else {
- Some(FixedLenSlice(prefix + suffix))
- }
+ let kind =
+ if slice.is_some() { VarLen(prefix, suffix) } else { FixedLen(prefix + suffix) };
+ Some(Slice(Slice { array_len, kind }))
}
PatKind::Or { .. } => {
bug!("support for or-patterns has not been fully implemented yet.");
) -> Vec<Constructor<'tcx>> {
let ty = pcx.ty;
let mut split_ctors = Vec::with_capacity(ctors.len());
+ debug!("split_grouped_constructors({:#?}, {:#?})", matrix, ctors);
for ctor in ctors.into_iter() {
match ctor {
.map(IntRange),
);
}
- VarLenSlice(self_prefix, self_suffix) => {
+ Slice(Slice { array_len, kind: VarLen(self_prefix, self_suffix) }) => {
// The exhaustiveness-checking paper does not include any details on
// checking variable-length slice patterns. However, they are matched
// by an infinite collection of fixed-length array patterns.
_ => {}
}
}
- PatKind::Slice { ref prefix, slice: None, ref suffix } => {
+ PatKind::Slice { ref prefix, slice: None, ref suffix }
+ | PatKind::Array { ref prefix, slice: None, ref suffix } => {
let fixed_len = prefix.len() as u64 + suffix.len() as u64;
max_fixed_len = cmp::max(max_fixed_len, fixed_len);
}
- PatKind::Slice { ref prefix, slice: Some(_), ref suffix } => {
+ PatKind::Slice { ref prefix, slice: Some(_), ref suffix }
+ | PatKind::Array { ref prefix, slice: Some(_), ref suffix } => {
max_prefix_len = cmp::max(max_prefix_len, prefix.len() as u64);
max_suffix_len = cmp::max(max_suffix_len, suffix.len() as u64);
}
max_prefix_len = max_fixed_len + 1 - max_suffix_len;
}
- // `ctor` originally covered the range `(self_prefix + self_suffix..infinity)`. We
- // now split it into two: lengths smaller than `max_prefix_len + max_suffix_len`
- // are treated independently as fixed-lengths slices, and lengths above are
- // captured by a final VarLenSlice constructor.
- split_ctors.extend(
- (self_prefix + self_suffix..max_prefix_len + max_suffix_len).map(FixedLenSlice),
- );
- split_ctors.push(VarLenSlice(max_prefix_len, max_suffix_len));
+ match array_len {
+ Some(len) => {
+ let kind = if max_prefix_len + max_suffix_len < len {
+ VarLen(max_prefix_len, max_suffix_len)
+ } else {
+ FixedLen(len)
+ };
+ split_ctors.push(Slice(Slice { array_len, kind }));
+ }
+ None => {
+ // `ctor` originally covered the range `(self_prefix +
+ // self_suffix..infinity)`. We now split it into two: lengths smaller than
+ // `max_prefix_len + max_suffix_len` are treated independently as
+ // fixed-lengths slices, and lengths above are captured by a final VarLen
+ // constructor.
+ split_ctors.extend(
+ (self_prefix + self_suffix..max_prefix_len + max_suffix_len)
+ .map(|len| Slice(Slice { array_len, kind: FixedLen(len) })),
+ );
+ split_ctors.push(Slice(Slice {
+ array_len,
+ kind: VarLen(max_prefix_len, max_suffix_len),
+ }));
+ }
+ }
}
// Any other constructor can be used unchanged.
_ => split_ctors.push(ctor),
}
}
+ debug!("split_grouped_constructors(..)={:#?}", split_ctors);
split_ctors
}
PatKind::Array { ref prefix, ref slice, ref suffix }
| PatKind::Slice { ref prefix, ref slice, ref suffix } => match *constructor {
- FixedLenSlice(..) | VarLenSlice(..) => {
+ Slice(_) => {
let pat_len = prefix.len() + suffix.len();
if let Some(slice_count) = ctor_wild_subpatterns.len().checked_sub(pat_len) {
if slice_count == 0 || slice.is_some() {
fn check_trait_fn_not_async(&self, span: Span, asyncness: IsAsync) {
if asyncness.is_async() {
- struct_span_err!(self.session, span, E0706,
- "trait fns cannot be declared `async`").emit()
+ struct_span_err!(self.session, span, E0706, "trait fns cannot be declared `async`")
+ .note("`async` trait functions are not currently supported")
+ .note("consider using the `async-trait` crate: \
+ https://crates.io/crates/async-trait")
+ .emit();
}
}
+++ /dev/null
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_plugin_impl"
-version = "0.0.0"
-build = false
-edition = "2018"
-
-[lib]
-name = "rustc_plugin_impl"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc = { path = "../librustc" }
-rustc_metadata = { path = "../librustc_metadata" }
-syntax = { path = "../libsyntax" }
-syntax_expand = { path = "../libsyntax_expand" }
-syntax_pos = { path = "../libsyntax_pos" }
-rustc_error_codes = { path = "../librustc_error_codes" }
+++ /dev/null
-//! Used by `rustc` when compiling a plugin crate.
-
-use syntax::attr;
-use syntax::symbol::sym;
-use syntax_pos::Span;
-use rustc::hir::itemlikevisit::ItemLikeVisitor;
-use rustc::hir;
-use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc::ty::TyCtxt;
-use rustc::ty::query::Providers;
-
-struct RegistrarFinder {
- registrars: Vec<(hir::HirId, Span)> ,
-}
-
-impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
- fn visit_item(&mut self, item: &hir::Item) {
- if let hir::ItemKind::Fn(..) = item.kind {
- if attr::contains_name(&item.attrs, sym::plugin_registrar) {
- self.registrars.push((item.hir_id, item.span));
- }
- }
- }
-
- fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
- }
-
- fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
- }
-}
-
-/// Finds the function marked with `#[plugin_registrar]`, if any.
-pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option<DefId> {
- tcx.plugin_registrar_fn(LOCAL_CRATE)
-}
-
-fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
- assert_eq!(cnum, LOCAL_CRATE);
-
- let mut finder = RegistrarFinder { registrars: Vec::new() };
- tcx.hir().krate().visit_all_item_likes(&mut finder);
-
- match finder.registrars.len() {
- 0 => None,
- 1 => {
- let (hir_id, _) = finder.registrars.pop().unwrap();
- Some(tcx.hir().local_def_id(hir_id))
- },
- _ => {
- let diagnostic = tcx.sess.diagnostic();
- let mut e = diagnostic.struct_err("multiple plugin registration functions found");
- for &(_, span) in &finder.registrars {
- e.span_note(span, "one is here");
- }
- e.emit();
- diagnostic.abort_if_errors();
- unreachable!();
- }
- }
-}
-
-
-pub fn provide(providers: &mut Providers<'_>) {
- *providers = Providers {
- plugin_registrar_fn,
- ..*providers
- };
-}
+++ /dev/null
-[package]
-authors = ["The Rust Project Developers"]
-name = "rustc_plugin"
-version = "0.0.0"
-build = false
-edition = "2018"
-
-[lib]
-name = "rustc_plugin"
-path = "lib.rs"
-doctest = false
-
-[dependencies]
-rustc_plugin_impl = { path = ".." }
+++ /dev/null
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
-#![feature(staged_api)]
-#![unstable(feature = "rustc_private", issue = "27812")]
-#![rustc_deprecated(since = "1.38.0", reason = "\
- import this through `rustc_driver::plugin` instead to make TLS work correctly. \
- See https://github.com/rust-lang/rust/issues/62717")]
-
-pub use rustc_plugin_impl::*;
+++ /dev/null
-//! Infrastructure for compiler plugins.
-//!
-//! Plugins are Rust libraries which extend the behavior of `rustc`
-//! in various ways.
-//!
-//! Plugin authors will use the `Registry` type re-exported by
-//! this module, along with its methods. The rest of the module
-//! is for use by `rustc` itself.
-//!
-//! To define a plugin, build a dylib crate with a
-//! `#[plugin_registrar]` function:
-//!
-//! ```no_run
-//! #![crate_name = "myplugin"]
-//! #![crate_type = "dylib"]
-//! #![feature(plugin_registrar)]
-//! #![feature(rustc_private)]
-//!
-//! extern crate rustc_driver;
-//! extern crate syntax;
-//! extern crate syntax_pos;
-//!
-//! use rustc_driver::plugin::Registry;
-//! use syntax_expand::base::{ExtCtxt, MacResult};
-//! use syntax_pos::Span;
-//! use syntax::tokenstream::TokenTree;
-//!
-//! #[plugin_registrar]
-//! pub fn plugin_registrar(reg: &mut Registry) {
-//! reg.register_macro("mymacro", expand_mymacro);
-//! }
-//!
-//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box<MacResult> {
-//! unimplemented!()
-//! }
-//!
-//! # fn main() {}
-//! ```
-//!
-//! WARNING: We currently don't check that the registrar function
-//! has the appropriate type!
-//!
-//! To use a plugin while compiling another crate:
-//!
-//! ```rust
-//! #![feature(plugin)]
-//! #![plugin(myplugin)]
-//! ```
-//!
-//! See the [`plugin`
-//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
-//! of the Unstable Book for more examples.
-
-#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
-
-#![feature(nll)]
-
-#![recursion_limit="256"]
-
-pub use registry::Registry;
-
-pub mod registry;
-pub mod load;
-pub mod build;
+++ /dev/null
-//! Used by `rustc` when loading a plugin.
-
-use rustc::middle::cstore::MetadataLoader;
-use rustc::session::Session;
-use rustc_metadata::locator;
-use crate::registry::Registry;
-
-use std::borrow::ToOwned;
-use std::env;
-use std::mem;
-use std::path::PathBuf;
-use syntax::ast;
-use syntax::struct_span_err;
-use syntax::symbol::{Symbol, kw, sym};
-use syntax_pos::{Span, DUMMY_SP};
-
-use rustc_error_codes::*;
-
-/// Pointer to a registrar function.
-pub type PluginRegistrarFun =
- fn(&mut Registry<'_>);
-
-pub struct PluginRegistrar {
- pub fun: PluginRegistrarFun,
- pub args: Vec<ast::NestedMetaItem>,
-}
-
-struct PluginLoader<'a> {
- sess: &'a Session,
- metadata_loader: &'a dyn MetadataLoader,
- plugins: Vec<PluginRegistrar>,
-}
-
-fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
- struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
- .span_label(span, "malformed attribute")
- .emit();
-}
-
-/// Read plugin metadata and dynamically load registrar functions.
-pub fn load_plugins(sess: &Session,
- metadata_loader: &dyn MetadataLoader,
- krate: &ast::Crate,
- addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
- let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() };
-
- // do not report any error now. since crate attributes are
- // not touched by expansion, every use of plugin without
- // the feature enabled will result in an error later...
- if sess.features_untracked().plugin {
- for attr in &krate.attrs {
- if !attr.check_name(sym::plugin) {
- continue;
- }
-
- let plugins = match attr.meta_item_list() {
- Some(xs) => xs,
- None => continue,
- };
-
- for plugin in plugins {
- // plugins must have a name and can't be key = value
- let name = plugin.name_or_empty();
- if name != kw::Invalid && !plugin.is_value_str() {
- let args = plugin.meta_item_list().map(ToOwned::to_owned);
- loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
- } else {
- call_malformed_plugin_attribute(sess, attr.span);
- }
- }
- }
- }
-
- if let Some(plugins) = addl_plugins {
- for plugin in plugins {
- loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
- }
- }
-
- loader.plugins
-}
-
-impl<'a> PluginLoader<'a> {
- fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
- let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name);
-
- if let Some((lib, disambiguator)) = registrar {
- let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
- let fun = self.dylink_registrar(span, lib, symbol);
- self.plugins.push(PluginRegistrar {
- fun,
- args,
- });
- }
- }
-
- // Dynamically link a registrar function into the compiler process.
- fn dylink_registrar(&mut self,
- span: Span,
- path: PathBuf,
- symbol: String) -> PluginRegistrarFun {
- use rustc_metadata::dynamic_lib::DynamicLibrary;
-
- // Make sure the path contains a / or the linker will search for it.
- let path = env::current_dir().unwrap().join(&path);
-
- let lib = match DynamicLibrary::open(Some(&path)) {
- Ok(lib) => lib,
- // this is fatal: there are almost certainly macros we need
- // inside this crate, so continue would spew "macro undefined"
- // errors
- Err(err) => {
- self.sess.span_fatal(span, &err)
- }
- };
-
- unsafe {
- let registrar =
- match lib.symbol(&symbol) {
- Ok(registrar) => {
- mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
- }
- // again fatal if we can't register macros
- Err(err) => {
- self.sess.span_fatal(span, &err)
- }
- };
-
- // Intentionally leak the dynamic library. We can't ever unload it
- // since the library can make things that will live arbitrarily long
- // (e.g., an @-box cycle or a thread).
- mem::forget(lib);
-
- registrar
- }
- }
-}
+++ /dev/null
-//! Used by plugin crates to tell `rustc` about the plugins they provide.
-
-use rustc::lint::LintStore;
-use rustc::session::Session;
-
-use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
-use syntax_expand::base::MacroExpanderFn;
-use syntax::symbol::Symbol;
-use syntax::ast;
-use syntax_pos::Span;
-
-use std::borrow::ToOwned;
-
-/// Structure used to register plugins.
-///
-/// A plugin registrar function takes an `&mut Registry` and should call
-/// methods to register its plugins.
-///
-/// This struct has public fields and other methods for use by `rustc`
-/// itself. They are not documented here, and plugin authors should
-/// not use them.
-pub struct Registry<'a> {
- /// Compiler session. Useful if you want to emit diagnostic messages
- /// from the plugin registrar.
- pub sess: &'a Session,
-
- /// The `LintStore` allows plugins to register new lints.
- pub lint_store: &'a mut LintStore,
-
- #[doc(hidden)]
- pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
-
- #[doc(hidden)]
- pub krate_span: Span,
-
- #[doc(hidden)]
- pub syntax_exts: Vec<NamedSyntaxExtension>,
-
- #[doc(hidden)]
- pub llvm_passes: Vec<String>,
-}
-
-impl<'a> Registry<'a> {
- #[doc(hidden)]
- pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
- Registry {
- sess,
- lint_store,
- args_hidden: None,
- krate_span,
- syntax_exts: vec![],
- llvm_passes: vec![],
- }
- }
-
- /// Gets the plugin's arguments, if any.
- ///
- /// These are specified inside the `plugin` crate attribute as
- ///
- /// ```no_run
- /// #![plugin(my_plugin_name(... args ...))]
- /// ```
- ///
- /// Returns empty slice in case the plugin was loaded
- /// with `--extra-plugins`
- pub fn args(&self) -> &[ast::NestedMetaItem] {
- self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
- }
-
- /// Register a syntax extension of any kind.
- ///
- /// This is the most general hook into `libsyntax`'s expansion behavior.
- pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
- self.syntax_exts.push((name, extension));
- }
-
- /// Register a macro of the usual kind.
- ///
- /// This is a convenience wrapper for `register_syntax_extension`.
- /// It builds for you a `SyntaxExtensionKind::LegacyBang` that calls `expander`,
- /// and also takes care of interning the macro's name.
- pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
- let kind = SyntaxExtensionKind::LegacyBang(Box::new(expander));
- let ext = SyntaxExtension::default(kind, self.sess.edition());
- self.register_syntax_extension(Symbol::intern(name), ext);
- }
-
- /// Register an LLVM pass.
- ///
- /// Registration with LLVM itself is handled through static C++ objects with
- /// constructors. This method simply adds a name to the list of passes to
- /// execute.
- pub fn register_llvm_pass(&mut self, name: &str) {
- self.llvm_passes.push(name.to_owned());
- }
-}
--- /dev/null
+[package]
+authors = ["The Rust Project Developers"]
+name = "rustc_plugin_impl"
+version = "0.0.0"
+build = false
+edition = "2018"
+
+[lib]
+name = "rustc_plugin_impl"
+path = "lib.rs"
+doctest = false
+
+[dependencies]
+rustc = { path = "../librustc" }
+rustc_metadata = { path = "../librustc_metadata" }
+syntax = { path = "../libsyntax" }
+syntax_expand = { path = "../libsyntax_expand" }
+syntax_pos = { path = "../libsyntax_pos" }
+rustc_error_codes = { path = "../librustc_error_codes" }
--- /dev/null
+//! Used by `rustc` when compiling a plugin crate.
+
+use syntax::attr;
+use syntax::symbol::sym;
+use syntax_pos::Span;
+use rustc::hir::itemlikevisit::ItemLikeVisitor;
+use rustc::hir;
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc::ty::TyCtxt;
+use rustc::ty::query::Providers;
+
+struct RegistrarFinder {
+ registrars: Vec<(hir::HirId, Span)> ,
+}
+
+impl<'v> ItemLikeVisitor<'v> for RegistrarFinder {
+ fn visit_item(&mut self, item: &hir::Item) {
+ if let hir::ItemKind::Fn(..) = item.kind {
+ if attr::contains_name(&item.attrs, sym::plugin_registrar) {
+ self.registrars.push((item.hir_id, item.span));
+ }
+ }
+ }
+
+ fn visit_trait_item(&mut self, _trait_item: &hir::TraitItem) {
+ }
+
+ fn visit_impl_item(&mut self, _impl_item: &hir::ImplItem) {
+ }
+}
+
+/// Finds the function marked with `#[plugin_registrar]`, if any.
+pub fn find_plugin_registrar(tcx: TyCtxt<'_>) -> Option<DefId> {
+ tcx.plugin_registrar_fn(LOCAL_CRATE)
+}
+
+fn plugin_registrar_fn(tcx: TyCtxt<'_>, cnum: CrateNum) -> Option<DefId> {
+ assert_eq!(cnum, LOCAL_CRATE);
+
+ let mut finder = RegistrarFinder { registrars: Vec::new() };
+ tcx.hir().krate().visit_all_item_likes(&mut finder);
+
+ match finder.registrars.len() {
+ 0 => None,
+ 1 => {
+ let (hir_id, _) = finder.registrars.pop().unwrap();
+ Some(tcx.hir().local_def_id(hir_id))
+ },
+ _ => {
+ let diagnostic = tcx.sess.diagnostic();
+ let mut e = diagnostic.struct_err("multiple plugin registration functions found");
+ for &(_, span) in &finder.registrars {
+ e.span_note(span, "one is here");
+ }
+ e.emit();
+ diagnostic.abort_if_errors();
+ unreachable!();
+ }
+ }
+}
+
+
+pub fn provide(providers: &mut Providers<'_>) {
+ *providers = Providers {
+ plugin_registrar_fn,
+ ..*providers
+ };
+}
--- /dev/null
+//! Infrastructure for compiler plugins.
+//!
+//! Plugins are Rust libraries which extend the behavior of `rustc`
+//! in various ways.
+//!
+//! Plugin authors will use the `Registry` type re-exported by
+//! this module, along with its methods. The rest of the module
+//! is for use by `rustc` itself.
+//!
+//! To define a plugin, build a dylib crate with a
+//! `#[plugin_registrar]` function:
+//!
+//! ```no_run
+//! #![crate_name = "myplugin"]
+//! #![crate_type = "dylib"]
+//! #![feature(plugin_registrar)]
+//! #![feature(rustc_private)]
+//!
+//! extern crate rustc_driver;
+//! extern crate syntax;
+//! extern crate syntax_pos;
+//!
+//! use rustc_driver::plugin::Registry;
+//! use syntax_expand::base::{ExtCtxt, MacResult};
+//! use syntax_pos::Span;
+//! use syntax::tokenstream::TokenTree;
+//!
+//! #[plugin_registrar]
+//! pub fn plugin_registrar(reg: &mut Registry) {
+//! reg.register_macro("mymacro", expand_mymacro);
+//! }
+//!
+//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box<MacResult> {
+//! unimplemented!()
+//! }
+//!
+//! # fn main() {}
+//! ```
+//!
+//! WARNING: We currently don't check that the registrar function
+//! has the appropriate type!
+//!
+//! To use a plugin while compiling another crate:
+//!
+//! ```rust
+//! #![feature(plugin)]
+//! #![plugin(myplugin)]
+//! ```
+//!
+//! See the [`plugin`
+//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
+//! of the Unstable Book for more examples.
+
+#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]
+
+#![feature(nll)]
+
+#![recursion_limit="256"]
+
+pub use registry::Registry;
+
+pub mod registry;
+pub mod load;
+pub mod build;
--- /dev/null
+//! Used by `rustc` when loading a plugin.
+
+use rustc::middle::cstore::MetadataLoader;
+use rustc::session::Session;
+use rustc_metadata::locator;
+use crate::registry::Registry;
+
+use std::borrow::ToOwned;
+use std::env;
+use std::mem;
+use std::path::PathBuf;
+use syntax::ast;
+use syntax::struct_span_err;
+use syntax::symbol::{Symbol, kw, sym};
+use syntax_pos::{Span, DUMMY_SP};
+
+use rustc_error_codes::*;
+
+/// Pointer to a registrar function.
+pub type PluginRegistrarFun =
+ fn(&mut Registry<'_>);
+
+pub struct PluginRegistrar {
+ pub fun: PluginRegistrarFun,
+ pub args: Vec<ast::NestedMetaItem>,
+}
+
+struct PluginLoader<'a> {
+ sess: &'a Session,
+ metadata_loader: &'a dyn MetadataLoader,
+ plugins: Vec<PluginRegistrar>,
+}
+
+fn call_malformed_plugin_attribute(sess: &Session, span: Span) {
+ struct_span_err!(sess, span, E0498, "malformed `plugin` attribute")
+ .span_label(span, "malformed attribute")
+ .emit();
+}
+
+/// Read plugin metadata and dynamically load registrar functions.
+pub fn load_plugins(sess: &Session,
+ metadata_loader: &dyn MetadataLoader,
+ krate: &ast::Crate,
+ addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
+ let mut loader = PluginLoader { sess, metadata_loader, plugins: Vec::new() };
+
+ // do not report any error now. since crate attributes are
+ // not touched by expansion, every use of plugin without
+ // the feature enabled will result in an error later...
+ if sess.features_untracked().plugin {
+ for attr in &krate.attrs {
+ if !attr.check_name(sym::plugin) {
+ continue;
+ }
+
+ let plugins = match attr.meta_item_list() {
+ Some(xs) => xs,
+ None => continue,
+ };
+
+ for plugin in plugins {
+ // plugins must have a name and can't be key = value
+ let name = plugin.name_or_empty();
+ if name != kw::Invalid && !plugin.is_value_str() {
+ let args = plugin.meta_item_list().map(ToOwned::to_owned);
+ loader.load_plugin(plugin.span(), name, args.unwrap_or_default());
+ } else {
+ call_malformed_plugin_attribute(sess, attr.span);
+ }
+ }
+ }
+ }
+
+ if let Some(plugins) = addl_plugins {
+ for plugin in plugins {
+ loader.load_plugin(DUMMY_SP, Symbol::intern(&plugin), vec![]);
+ }
+ }
+
+ loader.plugins
+}
+
+impl<'a> PluginLoader<'a> {
+ fn load_plugin(&mut self, span: Span, name: Symbol, args: Vec<ast::NestedMetaItem>) {
+ let registrar = locator::find_plugin_registrar(self.sess, self.metadata_loader, span, name);
+
+ if let Some((lib, disambiguator)) = registrar {
+ let symbol = self.sess.generate_plugin_registrar_symbol(disambiguator);
+ let fun = self.dylink_registrar(span, lib, symbol);
+ self.plugins.push(PluginRegistrar {
+ fun,
+ args,
+ });
+ }
+ }
+
+ // Dynamically link a registrar function into the compiler process.
+ fn dylink_registrar(&mut self,
+ span: Span,
+ path: PathBuf,
+ symbol: String) -> PluginRegistrarFun {
+ use rustc_metadata::dynamic_lib::DynamicLibrary;
+
+ // Make sure the path contains a / or the linker will search for it.
+ let path = env::current_dir().unwrap().join(&path);
+
+ let lib = match DynamicLibrary::open(Some(&path)) {
+ Ok(lib) => lib,
+ // this is fatal: there are almost certainly macros we need
+ // inside this crate, so continue would spew "macro undefined"
+ // errors
+ Err(err) => {
+ self.sess.span_fatal(span, &err)
+ }
+ };
+
+ unsafe {
+ let registrar =
+ match lib.symbol(&symbol) {
+ Ok(registrar) => {
+ mem::transmute::<*mut u8,PluginRegistrarFun>(registrar)
+ }
+ // again fatal if we can't register macros
+ Err(err) => {
+ self.sess.span_fatal(span, &err)
+ }
+ };
+
+ // Intentionally leak the dynamic library. We can't ever unload it
+ // since the library can make things that will live arbitrarily long
+ // (e.g., an @-box cycle or a thread).
+ mem::forget(lib);
+
+ registrar
+ }
+ }
+}
--- /dev/null
+//! Used by plugin crates to tell `rustc` about the plugins they provide.
+
+use rustc::lint::LintStore;
+use rustc::session::Session;
+
+use syntax_expand::base::{SyntaxExtension, SyntaxExtensionKind, NamedSyntaxExtension};
+use syntax_expand::base::MacroExpanderFn;
+use syntax::symbol::Symbol;
+use syntax::ast;
+use syntax_pos::Span;
+
+use std::borrow::ToOwned;
+
+/// Structure used to register plugins.
+///
+/// A plugin registrar function takes an `&mut Registry` and should call
+/// methods to register its plugins.
+///
+/// This struct has public fields and other methods for use by `rustc`
+/// itself. They are not documented here, and plugin authors should
+/// not use them.
+pub struct Registry<'a> {
+ /// Compiler session. Useful if you want to emit diagnostic messages
+ /// from the plugin registrar.
+ pub sess: &'a Session,
+
+ /// The `LintStore` allows plugins to register new lints.
+ pub lint_store: &'a mut LintStore,
+
+ #[doc(hidden)]
+ pub args_hidden: Option<Vec<ast::NestedMetaItem>>,
+
+ #[doc(hidden)]
+ pub krate_span: Span,
+
+ #[doc(hidden)]
+ pub syntax_exts: Vec<NamedSyntaxExtension>,
+
+ #[doc(hidden)]
+ pub llvm_passes: Vec<String>,
+}
+
+impl<'a> Registry<'a> {
+ #[doc(hidden)]
+ pub fn new(sess: &'a Session, lint_store: &'a mut LintStore, krate_span: Span) -> Registry<'a> {
+ Registry {
+ sess,
+ lint_store,
+ args_hidden: None,
+ krate_span,
+ syntax_exts: vec![],
+ llvm_passes: vec![],
+ }
+ }
+
+ /// Gets the plugin's arguments, if any.
+ ///
+ /// These are specified inside the `plugin` crate attribute as
+ ///
+ /// ```no_run
+ /// #![plugin(my_plugin_name(... args ...))]
+ /// ```
+ ///
+ /// Returns empty slice in case the plugin was loaded
+ /// with `--extra-plugins`
+ pub fn args(&self) -> &[ast::NestedMetaItem] {
+ self.args_hidden.as_ref().map(|v| &v[..]).unwrap_or(&[])
+ }
+
+ /// Register a syntax extension of any kind.
+ ///
+ /// This is the most general hook into `libsyntax`'s expansion behavior.
+ pub fn register_syntax_extension(&mut self, name: ast::Name, extension: SyntaxExtension) {
+ self.syntax_exts.push((name, extension));
+ }
+
+ /// Register a macro of the usual kind.
+ ///
+ /// This is a convenience wrapper for `register_syntax_extension`.
+ /// It builds for you a `SyntaxExtensionKind::LegacyBang` that calls `expander`,
+ /// and also takes care of interning the macro's name.
+ pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
+ let kind = SyntaxExtensionKind::LegacyBang(Box::new(expander));
+ let ext = SyntaxExtension::default(kind, self.sess.edition());
+ self.register_syntax_extension(Symbol::intern(name), ext);
+ }
+
+ /// Register an LLVM pass.
+ ///
+ /// Registration with LLVM itself is handled through static C++ objects with
+ /// constructors. This method simply adds a name to the list of passes to
+ /// execute.
+ pub fn register_llvm_pass(&mut self, name: &str) {
+ self.llvm_passes.push(name.to_owned());
+ }
+}
options: TargetOptions {
linker: Some("rust-lld".to_string()),
cpu: "generic-rv32".to_string(),
- max_atomic_width: None,
+ max_atomic_width: Some(0),
atomic_cas: false,
features: String::new(),
executables: true,
options: TargetOptions {
linker: Some("rust-lld".to_string()),
cpu: "generic-rv32".to_string(),
- // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86005
- max_atomic_width: None, //Some(32),
+ max_atomic_width: Some(0),
atomic_cas: false,
features: "+m,+c".to_string(),
executables: true,
static_files::source_serif_pro::ITALIC)?;
write(cx.dst.join("SourceSerifPro-LICENSE.md"),
static_files::source_serif_pro::LICENSE)?;
- write(cx.dst.join("SourceCodePro-Regular.woff"),
+ write(cx.dst.join("SourceCodePro-Regular.ttf.woff"),
static_files::source_code_pro::REGULAR)?;
- write(cx.dst.join("SourceCodePro-Semibold.woff"),
+ write(cx.dst.join("SourceCodePro-Semibold.ttf.woff"),
static_files::source_code_pro::SEMIBOLD)?;
+ write(cx.dst.join("SourceCodePro-It.ttf.woff"),
+ static_files::source_code_pro::ITALIC)?;
write(cx.dst.join("SourceCodePro-LICENSE.txt"),
static_files::source_code_pro::LICENSE)?;
write(cx.dst.join("LICENSE-MIT.txt"),
Copyright (c) Nicolas Gallagher and Jonathan Neal.
Licensed under the MIT license (see LICENSE-MIT.txt).
-* Source Code Pro (SourceCodePro-Regular.woff, SourceCodePro-Semibold.woff):
+* Source Code Pro (SourceCodePro-Regular.ttf.woff,
+ SourceCodePro-Semibold.ttf.woff, SourceCodePro-It.ttf.woff):
Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/),
with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark
font-weight: 400;
/* Avoid using locally installed font because bad versions are in circulation:
* see https://github.com/rust-lang/rust/issues/24355 */
- src: url("SourceCodePro-Regular.woff") format('woff');
+ src: url("SourceCodePro-Regular.ttf.woff") format('woff');
+}
+@font-face {
+ font-family: 'Source Code Pro';
+ font-style: italic;
+ font-weight: 400;
+ src: url("SourceCodePro-It.ttf.woff") format('woff');
}
@font-face {
font-family: 'Source Code Pro';
font-style: normal;
font-weight: 600;
- src: url("SourceCodePro-Semibold.woff") format('woff');
+ src: url("SourceCodePro-Semibold.ttf.woff") format('woff');
}
* {
/// Files related to the Source Code Pro font.
pub mod source_code_pro {
- /// The file `SourceCodePro-Regular.woff`, the Regular variant of the Source Code Pro font.
- pub static REGULAR: &'static [u8] = include_bytes!("static/SourceCodePro-Regular.woff");
+ /// The file `SourceCodePro-Regular.ttf.woff`, the Regular variant of the Source Code Pro font.
+ pub static REGULAR: &'static [u8] = include_bytes!("static/SourceCodePro-Regular.ttf.woff");
- /// The file `SourceCodePro-Semibold.woff`, the Semibold variant of the Source Code Pro font.
- pub static SEMIBOLD: &'static [u8] = include_bytes!("static/SourceCodePro-Semibold.woff");
+ /// The file `SourceCodePro-Semibold.ttf.woff`, the Semibold variant of the Source Code Pro
+ /// font.
+ pub static SEMIBOLD: &'static [u8] = include_bytes!("static/SourceCodePro-Semibold.ttf.woff");
+
+ /// The file `SourceCodePro-It.ttf.woff`, the Italic variant of the Source Code Pro font.
+ pub static ITALIC: &'static [u8] = include_bytes!("static/SourceCodePro-It.ttf.woff");
/// The file `SourceCodePro-LICENSE.txt`, the license text of the Source Code Pro font.
pub static LICENSE: &'static [u8] = include_bytes!("static/SourceCodePro-LICENSE.txt");
// fallback implementation to use as well.
//
// Due to rust-lang/rust#18804, make sure this is not generic!
-#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "hermit", target_os = "redox",
+#[cfg(any(target_os = "linux", target_os = "fuchsia", target_os = "redox",
target_os = "emscripten"))]
pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
use crate::mem;
--- /dev/null
+// edition:2018
+trait T {
+ async fn foo() {} //~ ERROR trait fns cannot be declared `async`
+ async fn bar(&self) {} //~ ERROR trait fns cannot be declared `async`
+}
+
+fn main() {}
--- /dev/null
+error[E0706]: trait fns cannot be declared `async`
+ --> $DIR/async-trait-fn.rs:3:5
+ |
+LL | async fn foo() {}
+ | ^^^^^^^^^^^^^^^^^
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error[E0706]: trait fns cannot be declared `async`
+ --> $DIR/async-trait-fn.rs:4:5
+ |
+LL | async fn bar(&self) {}
+ | ^^^^^^^^^^^^^^^^^^^^^^
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0706`.
|
LL | async fn foo() {}
| ^^^^^^^^^^^^^^^^^
+ |
+ = note: `async` trait functions are not currently supported
+ = note: consider using the `async-trait` crate: https://crates.io/crates/async-trait
error: aborting due to 10 previous errors
-For more information about this error, try `rustc --explain E0670`.
+Some errors have detailed explanations: E0670, E0706.
+For more information about an error, try `rustc --explain E0670`.
--- /dev/null
+// check-pass
+
+// This used to cause a stack overflow in the compiler.
+
+#![feature(slice_patterns)]
+
+fn main() {
+ const LARGE_SIZE: usize = 1024 * 1024;
+ let [..] = [0u8; LARGE_SIZE];
+ match [0u8; LARGE_SIZE] {
+ [..] => {}
+ }
+}
-error[E0004]: non-exhaustive patterns: `&[_, _, _, _]` not covered
+error[E0004]: non-exhaustive patterns: `&[..]` not covered
--> $DIR/match-byte-array-patterns-2.rs:4:11
|
LL | match buf {
- | ^^^ pattern `&[_, _, _, _]` not covered
+ | ^^^ pattern `&[..]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
let s1: &[bool; 1] = &[false; 1];
let s2: &[bool; 2] = &[false; 2];
let s3: &[bool; 3] = &[false; 3];
+ let s10: &[bool; 10] = &[false; 10];
+
+ match s2 {
+ //~^ ERROR `&[false, _]` not covered
+ [true, .., true] => {}
+ }
+ match s3 {
+ //~^ ERROR `&[false, ..]` not covered
+ [true, .., true] => {}
+ }
+ match s10 {
+ //~^ ERROR `&[false, ..]` not covered
+ [true, .., true] => {}
+ }
match s1 {
[true, ..] => {}
[.., false] => {}
}
match s3 {
- //~^ ERROR `&[false, _, true]` not covered
+ //~^ ERROR `&[false, .., true]` not covered
[true, ..] => {}
[.., false] => {}
}
[.., false] => {}
}
- match s3 {
- //~^ ERROR `&[false, _, _]` not covered
- [true, .., true] => {}
- }
match s {
//~^ ERROR `&[_, ..]` not covered
[] => {}
-error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:13:11
+error[E0004]: non-exhaustive patterns: `&[false, _]` not covered
+ --> $DIR/slice-patterns-exhaustiveness.rs:10:11
|
LL | match s2 {
- | ^^ pattern `&[false, true]` not covered
+ | ^^ pattern `&[false, _]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-error[E0004]: non-exhaustive patterns: `&[false, _, true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:18:11
+error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
+ --> $DIR/slice-patterns-exhaustiveness.rs:14:11
|
LL | match s3 {
- | ^^ pattern `&[false, _, true]` not covered
+ | ^^ pattern `&[false, ..]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:23:11
+error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
+ --> $DIR/slice-patterns-exhaustiveness.rs:18:11
|
-LL | match s {
- | ^ pattern `&[false, .., true]` not covered
+LL | match s10 {
+ | ^^^ pattern `&[false, ..]` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
+ --> $DIR/slice-patterns-exhaustiveness.rs:27:11
+ |
+LL | match s2 {
+ | ^^ pattern `&[false, true]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-error[E0004]: non-exhaustive patterns: `&[false, _, _]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:30:11
+error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
+ --> $DIR/slice-patterns-exhaustiveness.rs:32:11
|
LL | match s3 {
- | ^^ pattern `&[false, _, _]` not covered
+ | ^^ pattern `&[false, .., true]` not covered
+ |
+ = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+
+error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
+ --> $DIR/slice-patterns-exhaustiveness.rs:37:11
+ |
+LL | match s {
+ | ^ pattern `&[false, .., true]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:34:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:44:11
|
LL | match s {
| ^ pattern `&[_, ..]` not covered
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:38:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:48:11
|
LL | match s {
| ^ pattern `&[_, _, ..]` not covered
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:43:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:53:11
|
LL | match s {
| ^ pattern `&[false, ..]` not covered
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:48:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:58:11
|
LL | match s {
| ^ pattern `&[false, _, ..]` not covered
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:54:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:64:11
|
LL | match s {
| ^ pattern `&[_, .., false]` not covered
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:61:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:71:11
|
LL | match s {
| ^ pattern `&[_, _, .., true]` not covered
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
- --> $DIR/slice-patterns-exhaustiveness.rs:68:11
+ --> $DIR/slice-patterns-exhaustiveness.rs:78:11
|
LL | match s {
| ^ pattern `&[true, _, .., _]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-error: aborting due to 11 previous errors
+error: aborting due to 13 previous errors
For more information about this error, try `rustc --explain E0004`.