Remove SymbolStr.

By changing `as_str()` to take `&self` instead of `self`, we can just
return `&str`. We're still lying about lifetimes, but it's a smaller lie
than before, where `SymbolStr` contained a (fake) `&'static str`!
This commit is contained in:
Nicholas Nethercote 2021-12-15 08:32:21 +11:00
parent 22f8bde876
commit 8cddcd39ba
34 changed files with 125 additions and 182 deletions

View File

@ -369,7 +369,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
TodoItem::Static(def_id) => {
//println!("static {:?}", def_id);
let section_name = tcx.codegen_fn_attrs(def_id).link_section.map(|s| s.as_str());
let section_name = tcx.codegen_fn_attrs(def_id).link_section;
let alloc = tcx.eval_static_initializer(def_id).unwrap();
@ -388,6 +388,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
if let Some(section_name) = section_name {
let (segment_name, section_name) = if tcx.sess.target.is_like_osx {
let section_name = section_name.as_str();
if let Some(names) = section_name.split_once(',') {
names
} else {
@ -397,7 +398,7 @@ fn define_all_allocs(tcx: TyCtxt<'_>, module: &mut dyn Module, cx: &mut Constant
));
}
} else {
("", &*section_name)
("", section_name.as_str())
};
data_ctx.set_segment_section(segment_name, section_name);
}

View File

@ -2087,8 +2087,8 @@ fn prepare_enum_metadata(
let item_name;
let discriminant_name = match enum_type.kind() {
ty::Adt(..) => {
item_name = tcx.item_name(enum_def_id).as_str();
&*item_name
item_name = tcx.item_name(enum_def_id);
item_name.as_str()
}
ty::Generator(..) => enum_name.as_str(),
_ => bug!(),
@ -2563,7 +2563,8 @@ pub fn create_global_var_metadata(cx: &CodegenCx<'ll, '_>, def_id: DefId, global
let is_local_to_unit = is_node_local_to_unit(cx, def_id);
let variable_type = Instance::mono(cx.tcx, def_id).ty(cx.tcx, ty::ParamEnv::reveal_all());
let type_metadata = type_metadata(cx, variable_type, span);
let var_name = tcx.item_name(def_id).as_str();
let var_name = tcx.item_name(def_id);
let var_name = var_name.as_str();
let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id)).name;
// When empty, linkage_name field is omitted,
// which is what we want for no_mangle statics

View File

@ -170,8 +170,8 @@ fn mod_file_path_from_attr(
) -> Option<PathBuf> {
// Extract path string from first `#[path = "path_string"]` attribute.
let first_path = attrs.iter().find(|at| at.has_name(sym::path))?;
let path_string = match first_path.value_str() {
Some(s) => s.as_str(),
let path_sym = match first_path.value_str() {
Some(s) => s,
None => {
// This check is here mainly to catch attempting to use a macro,
// such as #[path = concat!(...)]. This isn't currently supported
@ -189,14 +189,16 @@ fn mod_file_path_from_attr(
}
};
let path_str = path_sym.as_str();
// On windows, the base path might have the form
// `\\?\foo\bar` in which case it does not tolerate
// mixed `/` and `\` separators, so canonicalize
// `/` to `\`.
#[cfg(windows)]
let path_string = path_string.replace("/", "\\");
let path_str = path_str.replace("/", "\\");
Some(dir_path.join(&*path_string))
Some(dir_path.join(path_str))
}
/// Returns a path to a module.

View File

@ -1049,8 +1049,8 @@ fn encode_and_write_metadata(
let need_metadata_file = tcx.sess.opts.output_types.contains_key(&OutputType::Metadata);
if need_metadata_file {
let crate_name = &tcx.crate_name(LOCAL_CRATE).as_str();
let out_filename = filename_for_metadata(tcx.sess, crate_name, outputs);
let crate_name = tcx.crate_name(LOCAL_CRATE);
let out_filename = filename_for_metadata(tcx.sess, crate_name.as_str(), outputs);
// To avoid races with another rustc process scanning the output directory,
// we need to write the file somewhere else and atomically move it to its
// final destination, with an `fs::rename` call. In order for the rename to

View File

@ -9,7 +9,7 @@ use rustc_middle::ty::subst::InternalSubsts;
use rustc_parse_format::{ParseMode, Parser, Piece};
use rustc_session::lint::FutureIncompatibilityReason;
use rustc_span::edition::Edition;
use rustc_span::{hygiene, sym, symbol::kw, symbol::SymbolStr, InnerSpan, Span, Symbol};
use rustc_span::{hygiene, sym, symbol::kw, InnerSpan, Span, Symbol};
use rustc_trait_selection::infer::InferCtxtExt;
declare_lint! {
@ -78,7 +78,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
// The argument is *not* a string literal.
let (span, panic, symbol_str) = panic_call(cx, f);
let (span, panic, symbol) = panic_call(cx, f);
if in_external_macro(cx.sess(), span) {
// Nothing that can be done about it in the current crate.
@ -103,7 +103,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
cx.struct_span_lint(NON_FMT_PANICS, arg_span, |lint| {
let mut l = lint.build("panic message is not a string literal");
l.note(&format!("this usage of {}!() is deprecated; it will be a hard error in Rust 2021", symbol_str));
l.note(&format!("this usage of {}!() is deprecated; it will be a hard error in Rust 2021", symbol));
l.note("for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/panic-macro-consistency.html>");
if !is_arg_inside_call(arg_span, span) {
// No clue where this argument is coming from.
@ -112,7 +112,7 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
}
if arg_macro.map_or(false, |id| cx.tcx.is_diagnostic_item(sym::format_macro, id)) {
// A case of `panic!(format!(..))`.
l.note(format!("the {}!() macro supports formatting, so there's no need for the format!() macro here", symbol_str).as_str());
l.note(format!("the {}!() macro supports formatting, so there's no need for the format!() macro here", symbol).as_str());
if let Some((open, close, _)) = find_delimiters(cx, arg_span) {
l.multipart_suggestion(
"remove the `format!(..)` macro call",
@ -301,7 +301,7 @@ fn find_delimiters<'tcx>(cx: &LateContext<'tcx>, span: Span) -> Option<(Span, Sp
))
}
fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol, SymbolStr) {
fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span, Symbol, Symbol) {
let mut expn = f.span.ctxt().outer_expn_data();
let mut panic_macro = kw::Empty;
@ -328,7 +328,7 @@ fn panic_call<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>) -> (Span,
let macro_symbol =
if let hygiene::ExpnKind::Macro(_, symbol) = expn.kind { symbol } else { sym::panic };
(expn.call_site, panic_macro, macro_symbol.as_str())
(expn.call_site, panic_macro, macro_symbol)
}
fn is_arg_inside_call(arg: Span, call: Span) -> bool {

View File

@ -976,7 +976,8 @@ impl CrateError {
let candidates = libraries
.iter()
.map(|lib| {
let crate_name = &lib.metadata.get_root().name().as_str();
let crate_name = lib.metadata.get_root().name();
let crate_name = crate_name.as_str();
let mut paths = lib.source.paths();
// This `unwrap()` should be okay because there has to be at least one

View File

@ -21,7 +21,7 @@ pub mod lib_features {
.map(|(f, s)| (*f, Some(*s)))
.chain(self.unstable.iter().map(|f| (*f, None)))
.collect();
all_features.sort_unstable_by_key(|f| f.0.as_str());
all_features.sort_unstable_by(|a, b| a.0.as_str().partial_cmp(b.0.as_str()).unwrap());
all_features
}
}

View File

@ -131,8 +131,7 @@ pub fn report_unstable(
/// deprecated (i.e., whether X is not greater than the current rustc version).
pub fn deprecation_in_effect(depr: &Deprecation) -> bool {
let is_since_rustc_version = depr.is_since_rustc_version;
let since = depr.since.map(Symbol::as_str);
let since = since.as_deref();
let since = depr.since.as_ref().map(Symbol::as_str);
fn parse_version(ver: &str) -> Vec<u32> {
// We ignore non-integer components of the version (e.g., "nightly").
@ -197,7 +196,7 @@ fn deprecation_message(
let message = if is_in_effect {
format!("use of deprecated {} `{}`", kind, path)
} else {
let since = since.map(Symbol::as_str);
let since = since.as_ref().map(Symbol::as_str);
if since.as_deref() == Some("TBD") {
format!("use of {} `{}` that will be deprecated in a future Rust version", kind, path)

View File

@ -1216,8 +1216,8 @@ impl<'tcx> TyCtxt<'tcx> {
}
pub fn consider_optimizing<T: Fn() -> String>(self, msg: T) -> bool {
let cname = self.crate_name(LOCAL_CRATE).as_str();
self.sess.consider_optimizing(&cname, msg)
let cname = self.crate_name(LOCAL_CRATE);
self.sess.consider_optimizing(cname.as_str(), msg)
}
/// Obtain all lang items of this crate and all dependencies (recursively)

View File

@ -3,7 +3,7 @@ use std::cmp;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::LOCAL_CRATE;
use rustc_middle::mir::mono::{CodegenUnit, CodegenUnitNameBuilder};
use rustc_span::symbol::{Symbol, SymbolStr};
use rustc_span::symbol::Symbol;
use super::PartitioningCx;
use crate::partitioning::PreInliningPartitioning;
@ -24,11 +24,11 @@ pub fn merge_codegen_units<'tcx>(
// smallest into each other) we're sure to start off with a deterministic
// order (sorted by name). This'll mean that if two cgus have the same size
// the stable sort below will keep everything nice and deterministic.
codegen_units.sort_by_cached_key(|cgu| cgu.name().as_str());
codegen_units.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap());
// This map keeps track of what got merged into what.
let mut cgu_contents: FxHashMap<Symbol, Vec<SymbolStr>> =
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name().as_str()])).collect();
let mut cgu_contents: FxHashMap<Symbol, Vec<Symbol>> =
codegen_units.iter().map(|cgu| (cgu.name(), vec![cgu.name()])).collect();
// Merge the two smallest codegen units until the target size is reached.
while codegen_units.len() > cx.target_cgu_count {
@ -69,7 +69,7 @@ pub fn merge_codegen_units<'tcx>(
// were actually modified by merging.
.filter(|(_, cgu_contents)| cgu_contents.len() > 1)
.map(|(current_cgu_name, cgu_contents)| {
let mut cgu_contents: Vec<&str> = cgu_contents.iter().map(|s| &s[..]).collect();
let mut cgu_contents: Vec<&str> = cgu_contents.iter().map(|s| s.as_str()).collect();
// Sort the names, so things are deterministic and easy to
// predict.

View File

@ -208,7 +208,7 @@ pub fn partition<'tcx>(
internalization_candidates: _,
} = post_inlining;
result.sort_by_cached_key(|cgu| cgu.name().as_str());
result.sort_by(|a, b| a.name().as_str().partial_cmp(b.name().as_str()).unwrap());
result
}

View File

@ -1679,7 +1679,8 @@ impl<'a> Parser<'a> {
);
}
LitError::InvalidIntSuffix => {
let suf = suffix.expect("suffix error with no suffix").as_str();
let suf = suffix.expect("suffix error with no suffix");
let suf = suf.as_str();
if looks_like_width_suffix(&['i', 'u'], &suf) {
// If it looks like a width, try to be helpful.
let msg = format!("invalid width `{}` for integer literal", &suf[1..]);
@ -1695,7 +1696,8 @@ impl<'a> Parser<'a> {
}
}
LitError::InvalidFloatSuffix => {
let suf = suffix.expect("suffix error with no suffix").as_str();
let suf = suffix.expect("suffix error with no suffix");
let suf = suf.as_str();
if looks_like_width_suffix(&['f'], &suf) {
// If it looks like a width, try to be helpful.
let msg = format!("invalid width `{}` for float literal", &suf[1..]);

View File

@ -61,8 +61,8 @@ impl<'p, 'c, 'tcx> QueryKeyStringBuilder<'p, 'c, 'tcx> {
match def_key.disambiguated_data.data {
DefPathData::CrateRoot => {
crate_name = self.tcx.crate_name(def_id.krate).as_str();
name = &*crate_name;
crate_name = self.tcx.crate_name(def_id.krate);
name = crate_name.as_str();
dis = "";
end_index = 3;
}

View File

@ -1,4 +1,3 @@
use std::cmp::Reverse;
use std::ptr;
use rustc_ast::{self as ast, Path};
@ -784,7 +783,7 @@ impl<'a> Resolver<'a> {
});
// Make sure error reporting is deterministic.
suggestions.sort_by_cached_key(|suggestion| suggestion.candidate.as_str());
suggestions.sort_by(|a, b| a.candidate.as_str().partial_cmp(b.candidate.as_str()).unwrap());
match find_best_match_for_name(
&suggestions.iter().map(|suggestion| suggestion.candidate).collect::<Vec<Symbol>>(),
@ -1481,12 +1480,12 @@ impl<'a, 'b> ImportResolver<'a, 'b> {
return None;
}
// Sort extern crate names in reverse order to get
// Sort extern crate names in *reverse* order to get
// 1) some consistent ordering for emitted diagnostics, and
// 2) `std` suggestions before `core` suggestions.
let mut extern_crate_names =
self.r.extern_prelude.iter().map(|(ident, _)| ident.name).collect::<Vec<_>>();
extern_crate_names.sort_by_key(|name| Reverse(name.as_str()));
extern_crate_names.sort_by(|a, b| b.as_str().partial_cmp(a.as_str()).unwrap());
for name in extern_crate_names.into_iter() {
// Replace first ident with a crate name and check if that is valid.

View File

@ -1353,7 +1353,7 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> {
let name = path[path.len() - 1].ident.name;
// Make sure error reporting is deterministic.
names.sort_by_cached_key(|suggestion| suggestion.candidate.as_str());
names.sort_by(|a, b| a.candidate.as_str().partial_cmp(b.candidate.as_str()).unwrap());
match find_best_match_for_name(
&names.iter().map(|suggestion| suggestion.candidate).collect::<Vec<Symbol>>(),

View File

@ -689,11 +689,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
hir_id: hir::HirId,
) {
let name = match fk {
intravisit::FnKind::ItemFn(id, _, _, _) => id.as_str(),
intravisit::FnKind::Method(id, _, _) => id.as_str(),
intravisit::FnKind::Closure => Symbol::intern("closure").as_str(),
intravisit::FnKind::ItemFn(id, _, _, _) => id.name,
intravisit::FnKind::Method(id, _, _) => id.name,
intravisit::FnKind::Closure => sym::closure,
};
let name: &str = &name;
let name: &str = name.as_str();
let span = span!(Level::DEBUG, "visit_fn", name);
let _enter = span.enter();
match fk {

View File

@ -1512,9 +1512,12 @@ impl Ident {
Ident::new(self.name, self.span.normalize_to_macro_rules())
}
/// Convert the name to a `SymbolStr`. This is a slowish operation because
/// it requires locking the symbol interner.
pub fn as_str(self) -> SymbolStr {
/// Access the underlying string. This is a slowish operation because it
/// requires locking the symbol interner.
///
/// Note that the lifetime of the return value is a lie. See
/// `Symbol::as_str()` for details.
pub fn as_str(&self) -> &str {
self.name.as_str()
}
}
@ -1650,12 +1653,17 @@ impl Symbol {
with_session_globals(|session_globals| session_globals.symbol_interner.intern(string))
}
/// Convert to a `SymbolStr`. This is a slowish operation because it
/// Access the underlying string. This is a slowish operation because it
/// requires locking the symbol interner.
pub fn as_str(self) -> SymbolStr {
with_session_globals(|session_globals| {
let symbol_str = session_globals.symbol_interner.get(self);
unsafe { SymbolStr { string: std::mem::transmute::<&str, &str>(symbol_str) } }
///
/// Note that the lifetime of the return value is a lie. It's not the same
/// as `&self`, but actually tied to the lifetime of the underlying
/// interner. Interners are long-lived, and there are very few of them, and
/// this function is typically used for short-lived things, so in practice
/// it works out ok.
pub fn as_str(&self) -> &str {
with_session_globals(|session_globals| unsafe {
std::mem::transmute::<&str, &str>(session_globals.symbol_interner.get(*self))
})
}
@ -1709,11 +1717,10 @@ impl<CTX> HashStable<CTX> for Symbol {
}
impl<CTX> ToStableHashKey<CTX> for Symbol {
type KeyType = SymbolStr;
type KeyType = String;
#[inline]
fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
self.as_str()
fn to_stable_hash_key(&self, _: &CTX) -> String {
self.as_str().to_string()
}
}
@ -1905,70 +1912,3 @@ impl Ident {
self.name.can_be_raw() && self.is_reserved()
}
}
/// An alternative to [`Symbol`], useful when the chars within the symbol need to
/// be accessed. It deliberately has limited functionality and should only be
/// used for temporary values.
///
/// Because the interner outlives any thread which uses this type, we can
/// safely treat `string` which points to interner data, as an immortal string,
/// as long as this type never crosses between threads.
//
// FIXME: ensure that the interner outlives any thread which uses `SymbolStr`,
// by creating a new thread right after constructing the interner.
#[derive(Clone, Eq, PartialOrd, Ord)]
pub struct SymbolStr {
string: &'static str,
}
// This impl allows a `SymbolStr` to be directly equated with a `String` or
// `&str`.
impl<T: std::ops::Deref<Target = str>> std::cmp::PartialEq<T> for SymbolStr {
fn eq(&self, other: &T) -> bool {
self.string == other.deref()
}
}
impl !Send for SymbolStr {}
impl !Sync for SymbolStr {}
/// This impl means that if `ss` is a `SymbolStr`:
/// - `*ss` is a `str`;
/// - `&*ss` is a `&str` (and `match &*ss { ... }` is a common pattern).
/// - `&ss as &str` is a `&str`, which means that `&ss` can be passed to a
/// function expecting a `&str`.
impl std::ops::Deref for SymbolStr {
type Target = str;
#[inline]
fn deref(&self) -> &str {
self.string
}
}
impl fmt::Debug for SymbolStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(self.string, f)
}
}
impl fmt::Display for SymbolStr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(self.string, f)
}
}
impl<CTX> HashStable<CTX> for SymbolStr {
#[inline]
fn hash_stable(&self, hcx: &mut CTX, hasher: &mut StableHasher) {
self.string.hash_stable(hcx, hasher)
}
}
impl<CTX> ToStableHashKey<CTX> for SymbolStr {
type KeyType = SymbolStr;
#[inline]
fn to_stable_hash_key(&self, _: &CTX) -> SymbolStr {
self.clone()
}
}

View File

@ -9,6 +9,7 @@ use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::ty::print::{Print, Printer};
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, Subst};
use rustc_middle::ty::{self, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeFoldable, UintTy};
use rustc_span::symbol::kw;
use rustc_target::abi::call::FnAbi;
use rustc_target::abi::Integer;
use rustc_target::spec::abi::Abi;
@ -702,12 +703,11 @@ impl Printer<'tcx> for &mut SymbolMangler<'tcx> {
// just to be able to handle disambiguators.
let disambiguated_field =
self.tcx.def_key(field_def.did).disambiguated_data;
let field_name =
disambiguated_field.data.get_opt_name().map(|s| s.as_str());
let field_name = disambiguated_field.data.get_opt_name();
self.push_disambiguator(
disambiguated_field.disambiguator as u64,
);
self.push_ident(&field_name.as_ref().map_or("", |s| &s[..]));
self.push_ident(field_name.unwrap_or(kw::Empty).as_str());
self = field.print(self)?;
}
@ -736,8 +736,8 @@ impl Printer<'tcx> for &mut SymbolMangler<'tcx> {
self.push("C");
let stable_crate_id = self.tcx.def_path_hash(cnum.as_def_id()).stable_crate_id();
self.push_disambiguator(stable_crate_id.to_u64());
let name = self.tcx.crate_name(cnum).as_str();
self.push_ident(&name);
let name = self.tcx.crate_name(cnum);
self.push_ident(name.as_str());
Ok(self)
}
@ -789,13 +789,13 @@ impl Printer<'tcx> for &mut SymbolMangler<'tcx> {
}
};
let name = disambiguated_data.data.get_opt_name().map(|s| s.as_str());
let name = disambiguated_data.data.get_opt_name();
self.path_append_ns(
print_prefix,
ns,
disambiguated_data.disambiguator as u64,
name.as_ref().map_or("", |s| &s[..]),
name.unwrap_or(kw::Empty).as_str(),
)
}

View File

@ -1038,7 +1038,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
.collect();
// Sort them by the name so we have a stable result.
names.sort_by_cached_key(|n| n.as_str());
names.sort_by(|a, b| a.as_str().partial_cmp(b.as_str()).unwrap());
names
}

View File

@ -26,7 +26,7 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_session::Session;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::DUMMY_SP;
use rustc_span::symbol::{kw, sym, Ident, Symbol, SymbolStr};
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{self, FileName, Loc};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
@ -2008,10 +2008,6 @@ impl Path {
self.segments.last().expect("segments were empty").name
}
crate fn last_name(&self) -> SymbolStr {
self.segments.last().expect("segments were empty").name.as_str()
}
crate fn whole_name(&self) -> String {
self.segments
.iter()

View File

@ -666,20 +666,18 @@ fn primitive_link(
needs_termination = true;
}
Some(&def_id) => {
let cname_str;
let cname_sym;
let loc = match m.extern_locations[&def_id.krate] {
ExternalLocation::Remote(ref s) => {
cname_str =
ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str();
Some(vec![s.trim_end_matches('/'), &cname_str[..]])
cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
Some(vec![s.trim_end_matches('/'), cname_sym.as_str()])
}
ExternalLocation::Local => {
cname_str =
ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str();
Some(if cx.current.first().map(|x| &x[..]) == Some(&cname_str[..]) {
cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
Some(if cx.current.first().map(|x| &x[..]) == Some(cname_sym.as_str()) {
iter::repeat("..").take(cx.current.len() - 1).collect()
} else {
let cname = iter::once(&cname_str[..]);
let cname = iter::once(cname_sym.as_str());
iter::repeat("..").take(cx.current.len()).chain(cname).collect()
})
}
@ -1401,9 +1399,9 @@ impl clean::ImportSource {
for seg in &self.path.segments[..self.path.segments.len() - 1] {
write!(f, "{}::", seg.name)?;
}
let name = self.path.last_name();
let name = self.path.last();
if let hir::def::Res::PrimTy(p) = self.path.res {
primitive_link(f, PrimitiveType::from(p), &*name, cx)?;
primitive_link(f, PrimitiveType::from(p), name.as_str(), cx)?;
} else {
write!(f, "{}", name)?;
}

View File

@ -315,7 +315,7 @@ impl<'tcx> Context<'tcx> {
};
let file = &file;
let symbol;
let krate_sym;
let (krate, path) = if cnum == LOCAL_CRATE {
if let Some(path) = self.shared.local_sources.get(file) {
(self.shared.layout.krate.as_str(), path)
@ -343,8 +343,8 @@ impl<'tcx> Context<'tcx> {
let mut fname = file.file_name().expect("source has no filename").to_os_string();
fname.push(".html");
path.push_str(&fname.to_string_lossy());
symbol = krate.as_str();
(&*symbol, &path)
krate_sym = krate;
(krate_sym.as_str(), &path)
};
let anchor = if with_lines {

View File

@ -1421,7 +1421,7 @@ fn render_impl(
let source_id = trait_
.and_then(|trait_| {
trait_.items.iter().find(|item| {
item.name.map(|n| n.as_str().eq(&name.as_str())).unwrap_or(false)
item.name.map(|n| n.as_str().eq(name.as_str())).unwrap_or(false)
})
})
.map(|item| format!("{}.{}", item.type_(), name));

View File

@ -239,9 +239,9 @@ fn item_module(w: &mut Buffer, cx: &Context<'_>, item: &clean::Item, items: &[cl
(true, false) => return Ordering::Greater,
}
}
let lhs = i1.name.unwrap_or(kw::Empty).as_str();
let rhs = i2.name.unwrap_or(kw::Empty).as_str();
compare_names(&lhs, &rhs)
let lhs = i1.name.unwrap_or(kw::Empty);
let rhs = i2.name.unwrap_or(kw::Empty);
compare_names(lhs.as_str(), rhs.as_str())
}
if cx.shared.sort_modules_alphabetically {

View File

@ -607,7 +607,7 @@ impl FromWithTcx<clean::Import> for Import {
},
Glob => Import {
source: import.source.path.whole_name(),
name: import.source.path.last_name().to_string(),
name: import.source.path.last().to_string(),
id: import.source.did.map(ItemId::from).map(from_item_id),
glob: true,
},

View File

@ -2153,8 +2153,8 @@ fn privacy_error(cx: &DocContext<'_>, diag_info: &DiagnosticInfo<'_>, path_str:
let sym;
let item_name = match diag_info.item.name {
Some(name) => {
sym = name.as_str();
&*sym
sym = name;
sym.as_str()
}
None => "<unknown>",
};

View File

@ -17,7 +17,7 @@ use rustc_semver::RustcVersion;
use rustc_session::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
use rustc_span::source_map::Span;
use rustc_span::sym;
use rustc_span::symbol::{Symbol, SymbolStr};
use rustc_span::symbol::Symbol;
use semver::Version;
static UNIX_SYSTEMS: &[&str] = &[
@ -310,8 +310,8 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
|| is_word(lint, sym::deprecated)
|| is_word(lint, sym!(unreachable_pub))
|| is_word(lint, sym!(unused))
|| extract_clippy_lint(lint).map_or(false, |s| s == "wildcard_imports")
|| extract_clippy_lint(lint).map_or(false, |s| s == "enum_glob_use")
|| extract_clippy_lint(lint).map_or(false, |s| s.as_str() == "wildcard_imports")
|| extract_clippy_lint(lint).map_or(false, |s| s.as_str() == "enum_glob_use")
{
return;
}
@ -370,7 +370,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
}
/// Returns the lint name if it is clippy lint.
fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<Symbol> {
if_chain! {
if let Some(meta_item) = lint.meta_item();
if meta_item.path.segments.len() > 1;
@ -378,7 +378,7 @@ fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
if tool_name.name == sym::clippy;
then {
let lint_name = meta_item.path.segments.last().unwrap().ident.name;
return Some(lint_name.as_str());
return Some(lint_name);
}
}
None
@ -387,7 +387,7 @@ fn extract_clippy_lint(lint: &NestedMetaItem) -> Option<SymbolStr> {
fn check_clippy_lint_names(cx: &LateContext<'_>, name: Symbol, items: &[NestedMetaItem]) {
for lint in items {
if let Some(lint_name) = extract_clippy_lint(lint) {
if lint_name == "restriction" && name != sym::allow {
if lint_name.as_str() == "restriction" && name != sym::allow {
span_lint_and_help(
cx,
BLANKET_CLIPPY_RESTRICTION_LINTS,

View File

@ -9,7 +9,7 @@ use rustc_middle::hir::map::Map;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
use rustc_span::symbol::SymbolStr;
use rustc_span::symbol::Symbol;
use rustc_span::{sym, Span};
declare_clippy_lint! {
@ -71,8 +71,8 @@ impl LateLintPass<'_> for MatchStrCaseMismatch {
visitor.visit_expr(match_expr);
if let Some(case_method) = visitor.case_method {
if let Some((bad_case_span, bad_case_str)) = verify_case(&case_method, arms) {
lint(cx, &case_method, bad_case_span, &bad_case_str);
if let Some((bad_case_span, bad_case_sym)) = verify_case(&case_method, arms) {
lint(cx, &case_method, bad_case_span, bad_case_sym.as_str());
}
}
}
@ -126,7 +126,7 @@ fn get_case_method(segment_ident_str: &str) -> Option<CaseMethod> {
}
}
fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(Span, SymbolStr)> {
fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(Span, Symbol)> {
let case_check = match case_method {
CaseMethod::LowerCase => |input: &str| -> bool { input.chars().all(|c| c.to_lowercase().next() == Some(c)) },
CaseMethod::AsciiLowerCase => |input: &str| -> bool { !input.chars().any(|c| c.is_ascii_uppercase()) },
@ -144,7 +144,7 @@ fn verify_case<'a>(case_method: &'a CaseMethod, arms: &'a [Arm<'_>]) -> Option<(
let input = symbol.as_str();
if !case_check(&input);
then {
return Some((lit.span, input));
return Some((lit.span, symbol));
}
}
}

View File

@ -78,7 +78,7 @@ use rustc_middle::lint::in_external_macro;
use rustc_middle::ty::{self, TraitRef, Ty, TyS};
use rustc_semver::RustcVersion;
use rustc_session::{declare_tool_lint, impl_lint_pass};
use rustc_span::symbol::SymbolStr;
use rustc_span::symbol::Symbol;
use rustc_span::{sym, Span};
use rustc_typeck::hir_ty_to_ty;
@ -1968,21 +1968,21 @@ impl_lint_pass!(Methods => [
]);
/// Extracts a method call name, args, and `Span` of the method name.
fn method_call<'tcx>(recv: &'tcx hir::Expr<'tcx>) -> Option<(SymbolStr, &'tcx [hir::Expr<'tcx>], Span)> {
fn method_call<'tcx>(recv: &'tcx hir::Expr<'tcx>) -> Option<(Symbol, &'tcx [hir::Expr<'tcx>], Span)> {
if let ExprKind::MethodCall(path, span, args, _) = recv.kind {
if !args.iter().any(|e| e.span.from_expansion()) {
return Some((path.ident.name.as_str(), args, span));
return Some((path.ident.name, args, span));
}
}
None
}
/// Same as `method_call` but the `SymbolStr` is dereferenced into a temporary `&str`
/// Same as `method_call` but the `Symbol` is dereferenced into a temporary `&str`
macro_rules! method_call {
($expr:expr) => {
method_call($expr)
.as_ref()
.map(|&(ref name, args, span)| (&**name, args, span))
.map(|&(ref name, args, span)| (name.as_str(), args, span))
};
}

View File

@ -407,6 +407,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
// Don't lint things expanded by #[derive(...)], etc or `await` desugaring
return;
}
let sym;
let binding = match expr.kind {
ExprKind::Path(ref qpath) if !matches!(qpath, hir::QPath::LangItem(..)) => {
let binding = last_path_segment(qpath).ident.as_str();
@ -423,7 +424,8 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
}
},
ExprKind::Field(_, ident) => {
let name = ident.as_str();
sym = ident.name;
let name = sym.as_str();
if name.starts_with('_') && !name.starts_with("__") {
Some(name)
} else {

View File

@ -48,7 +48,7 @@ impl LateLintPass<'_> for MultipleCrateVersions {
}
let metadata = unwrap_cargo_metadata!(cx, MULTIPLE_CRATE_VERSIONS, true);
let local_name = cx.tcx.crate_name(LOCAL_CRATE).as_str();
let local_name = cx.tcx.crate_name(LOCAL_CRATE);
let mut packages = metadata.packages;
packages.sort_by(|a, b| a.name.cmp(&b.name));
@ -56,7 +56,7 @@ impl LateLintPass<'_> for MultipleCrateVersions {
if let Some(resolve) = &metadata.resolve;
if let Some(local_id) = packages
.iter()
.find_map(|p| if p.name == *local_name { Some(&p.id) } else { None });
.find_map(|p| if p.name == local_name.as_str() { Some(&p.id) } else { None });
then {
for (name, group) in &packages.iter().group_by(|p| p.name.clone()) {
let group: Vec<&Package> = group.collect();

View File

@ -319,8 +319,8 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
if let ExprKind::Path(qpath) = &callee.kind;
let res = self.typeck_results.qpath_res(qpath, callee.hir_id);
if let Some(def_id) = res.opt_def_id();
let def_path: Vec<_> = self.lcx.get_def_path(def_id).into_iter().map(Symbol::as_str).collect();
let def_path: Vec<&str> = def_path.iter().take(4).map(|s| &**s).collect();
let def_path = self.lcx.get_def_path(def_id);
let def_path: Vec<&str> = def_path.iter().take(4).map(|s| s.as_str()).collect();
if let ["core", "num", int_impl, "max_value"] = *def_path;
then {
let value = match int_impl {

View File

@ -31,9 +31,9 @@ fn compare_items(a: &ast::Item, b: &ast::Item) -> Ordering {
(&ast::ItemKind::ExternCrate(ref a_name), &ast::ItemKind::ExternCrate(ref b_name)) => {
// `extern crate foo as bar;`
// ^^^ Comparing this.
let a_orig_name = a_name.map_or_else(|| a.ident.as_str(), rustc_span::Symbol::as_str);
let b_orig_name = b_name.map_or_else(|| b.ident.as_str(), rustc_span::Symbol::as_str);
let result = a_orig_name.cmp(&b_orig_name);
let a_orig_name = a_name.unwrap_or(a.ident.name);
let b_orig_name = b_name.unwrap_or(b.ident.name);
let result = a_orig_name.as_str().cmp(b_orig_name.as_str());
if result != Ordering::Equal {
return result;
}

View File

@ -95,15 +95,17 @@ pub(crate) enum ParserError {
impl<'a> Parser<'a> {
pub(crate) fn submod_path_from_attr(attrs: &[ast::Attribute], path: &Path) -> Option<PathBuf> {
let path_string = first_attr_value_str_by_name(attrs, sym::path)?.as_str();
let path_sym = first_attr_value_str_by_name(attrs, sym::path)?;
let path_str = path_sym.as_str();
// On windows, the base path might have the form
// `\\?\foo\bar` in which case it does not tolerate
// mixed `/` and `\` separators, so canonicalize
// `/` to `\`.
#[cfg(windows)]
let path_string = path_string.replace("/", "\\");
let path_str = path_str.replace("/", "\\");
Some(path.join(&*path_string))
Some(path.join(path_str))
}
pub(crate) fn parse_file_as_module(