use rustc_data_structures::parallel;
use rustc_data_structures::sync::{Lrc, OnceCell, WorkerLocal};
use rustc_data_structures::temp_dir::MaybeTempDir;
-use rustc_errors::{ErrorReported, PResult};
+use rustc_errors::{Applicability, ErrorReported, PResult};
use rustc_expand::base::ExtCtxt;
use rustc_hir::def_id::{StableCrateId, LOCAL_CRATE};
use rustc_hir::Crate;
use rustc_session::search_paths::PathKind;
use rustc_session::{Limit, Session};
use rustc_span::symbol::{sym, Ident, Symbol};
-use rustc_span::FileName;
+use rustc_span::{FileName, MultiSpan};
use rustc_trait_selection::traits;
use rustc_typeck as typeck;
use tempfile::Builder as TempFileBuilder;
let crate_attrs = krate.attrs.clone();
let extern_mod_loaded = |ident: Ident, attrs, items, span| {
- let krate = ast::Crate { attrs, items, span };
+ let krate = ast::Crate { attrs, items, span, is_placeholder: None };
pre_expansion_lint(sess, lint_store, &krate, &crate_attrs, &ident.name.as_str());
(krate.attrs, krate.items)
};
});
}
+ // Gate identifiers containing invalid Unicode codepoints that were recovered during lexing.
+ sess.parse_sess.bad_unicode_identifiers.with_lock(|identifiers| {
+ let mut identifiers: Vec<_> = identifiers.drain().collect();
+ identifiers.sort_by_key(|&(key, _)| key);
+ for (ident, mut spans) in identifiers.into_iter() {
+ spans.sort();
+ if ident == sym::ferris {
+ let first_span = spans[0];
+ sess.diagnostic()
+ .struct_span_err(
+ MultiSpan::from(spans),
+ "Ferris cannot be used as an identifier",
+ )
+ .span_suggestion(
+ first_span,
+ "try using their name instead",
+ "ferris".to_string(),
+ Applicability::MaybeIncorrect,
+ )
+ .emit();
+ } else {
+ sess.diagnostic().span_err(
+ MultiSpan::from(spans),
+ &format!("identifiers cannot contain emoji: `{}`", ident),
+ );
+ }
+ }
+ });
+
Ok(krate)
}