Auto merge of #77954 - JohnTitor:rollup-bpoy497, r=JohnTitor

Rollup of 9 pull requests

Successful merges:

 - #77570 (Allow ascii whitespace char for doc aliases )
 - #77739 (Remove unused code)
 - #77753 (Check html comments)
 - #77879 (Provide better documentation and help messages for x.py setup)
 - #77902 (Include aarch64-pc-windows-msvc in the dist manifests)
 - #77934 (Document -Z codegen-backend in the unstable book)
 - #77936 (Remove needless alloc_slice)
 - #77946 (Validate references to source scopes)
 - #77951 (Update books)

Failed merges:

r? `@ghost`
This commit is contained in:
bors 2020-10-14 23:11:04 +00:00
commit f42692b1cc
66 changed files with 307 additions and 789 deletions

View File

@ -167,13 +167,6 @@ pub enum GenericArgs {
}
impl GenericArgs {
pub fn is_parenthesized(&self) -> bool {
match *self {
Parenthesized(..) => true,
_ => false,
}
}
pub fn is_angle_bracketed(&self) -> bool {
match *self {
AngleBracketed(..) => true,
@ -857,13 +850,6 @@ impl BinOpKind {
}
}
pub fn is_shift(&self) -> bool {
match *self {
BinOpKind::Shl | BinOpKind::Shr => true,
_ => false,
}
}
pub fn is_comparison(&self) -> bool {
use BinOpKind::*;
// Note for developers: please keep this as is;
@ -873,11 +859,6 @@ impl BinOpKind {
And | Or | Add | Sub | Mul | Div | Rem | BitXor | BitAnd | BitOr | Shl | Shr => false,
}
}
/// Returns `true` if the binary operator takes its arguments by value
pub fn is_by_value(&self) -> bool {
!self.is_comparison()
}
}
pub type BinOp = Spanned<BinOpKind>;
@ -896,14 +877,6 @@ pub enum UnOp {
}
impl UnOp {
/// Returns `true` if the unary operator takes its argument by value
pub fn is_by_value(u: UnOp) -> bool {
match u {
UnOp::Neg | UnOp::Not => true,
_ => false,
}
}
pub fn to_string(op: UnOp) -> &'static str {
match op {
UnOp::Deref => "*",
@ -1753,13 +1726,6 @@ impl IntTy {
}
}
pub fn val_to_string(&self, val: i128) -> String {
// Cast to a `u128` so we can correctly print `INT128_MIN`. All integral types
// are parsed as `u128`, so we wouldn't want to print an extra negative
// sign.
format!("{}{}", val as u128, self.name_str())
}
pub fn bit_width(&self) -> Option<u64> {
Some(match *self {
IntTy::Isize => return None,
@ -1818,10 +1784,6 @@ impl UintTy {
}
}
pub fn val_to_string(&self, val: u128) -> String {
format!("{}{}", val, self.name_str())
}
pub fn bit_width(&self) -> Option<u64> {
Some(match *self {
UintTy::Usize => return None,

View File

@ -101,11 +101,6 @@ impl NestedMetaItem {
self.meta_item().is_some()
}
/// Returns `true` if the variant is `Literal`.
pub fn is_literal(&self) -> bool {
self.literal().is_some()
}
/// Returns `true` if `self` is a `MetaItem` and the meta item is a word.
pub fn is_word(&self) -> bool {
self.meta_item().map_or(false, |meta_item| meta_item.is_word())
@ -232,10 +227,6 @@ impl MetaItem {
pub fn is_value_str(&self) -> bool {
self.value_str().is_some()
}
pub fn is_meta_item_list(&self) -> bool {
self.meta_item_list().is_some()
}
}
impl AttrItem {

View File

@ -54,16 +54,6 @@ pub enum DelimToken {
NoDelim,
}
impl DelimToken {
pub fn len(self) -> usize {
if self == NoDelim { 0 } else { 1 }
}
pub fn is_empty(self) -> bool {
self == NoDelim
}
}
#[derive(Clone, Copy, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum LitKind {
Bool, // AST only, must never appear in a `Token`

View File

@ -295,12 +295,6 @@ impl TokenStream {
.collect(),
))
}
pub fn map<F: FnMut(TokenTree) -> TokenTree>(self, mut f: F) -> TokenStream {
TokenStream(Lrc::new(
self.0.iter().map(|(tree, is_joint)| (f(tree.clone()), *is_joint)).collect(),
))
}
}
// 99.5%+ of the time we have 1 or 2 elements in this vector.

View File

@ -231,7 +231,6 @@ impl AssocOp {
}
}
pub const PREC_RESET: i8 = -100;
pub const PREC_CLOSURE: i8 = -40;
pub const PREC_JUMP: i8 = -30;
pub const PREC_RANGE: i8 = -10;

View File

@ -118,11 +118,6 @@ pub fn SetUnnamedAddress(global: &'a Value, unnamed: UnnamedAddr) {
}
}
pub fn set_thread_local(global: &'a Value, is_thread_local: bool) {
unsafe {
LLVMSetThreadLocal(global, is_thread_local as Bool);
}
}
pub fn set_thread_local_mode(global: &'a Value, mode: ThreadLocalMode) {
unsafe {
LLVMSetThreadLocalMode(global, mode);

View File

@ -1519,8 +1519,6 @@ fn start_executing_work<B: ExtraBackendMethods>(
}
}
pub const CODEGEN_WORKER_ID: usize = usize::MAX;
/// `FatalError` is explicitly not `Send`.
#[must_use]
pub struct WorkerFatalError;

View File

@ -479,8 +479,6 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
}
}
pub const CODEGEN_WORKER_ID: usize = usize::MAX;
pub fn codegen_crate<B: ExtraBackendMethods>(
backend: B,
tcx: TyCtxt<'tcx>,

View File

@ -14,12 +14,6 @@ pub struct WorkQueue<T: Idx> {
}
impl<T: Idx> WorkQueue<T> {
/// Creates a new work queue with all the elements from (0..len).
#[inline]
pub fn with_all(len: usize) -> Self {
WorkQueue { deque: (0..len).map(T::new).collect(), set: BitSet::new_filled(len) }
}
/// Creates a new work queue that starts empty, where elements range from (0..len).
#[inline]
pub fn with_none(len: usize) -> Self {

View File

@ -121,11 +121,6 @@ impl Diagnostic {
self.level == Level::Cancelled
}
/// Set the sorting span.
pub fn set_sort_span(&mut self, sp: Span) {
self.sort_span = sp;
}
/// Adds a span/label to be included in the resulting snippet.
///
/// This is pushed onto the [`MultiSpan`] that was created when the diagnostic
@ -535,14 +530,6 @@ impl Diagnostic {
&self.message
}
/// Used by a lint. Copies over all details *but* the "main
/// message".
pub fn copy_details_not_message(&mut self, from: &Diagnostic) {
self.span = from.span.clone();
self.code = from.code.clone();
self.children.extend(from.children.iter().cloned())
}
/// Convenience function for internal use, clients should use one of the
/// public methods above.
pub fn sub(

View File

@ -510,8 +510,6 @@ impl Emitter for SilentEmitter {
fn emit_diagnostic(&mut self, _: &Diagnostic) {}
}
/// Maximum number of lines we will print for each error; arbitrary.
pub const MAX_HIGHLIGHT_LINES: usize = 6;
/// Maximum number of lines we will print for a multiline suggestion; arbitrary.
///
/// This should be replaced with a more involved mechanism to output multiline suggestions that

View File

@ -148,17 +148,6 @@ impl Annotatable {
}
}
pub fn map_item_or<F, G>(self, mut f: F, mut or: G) -> Annotatable
where
F: FnMut(P<ast::Item>) -> P<ast::Item>,
G: FnMut(Annotatable) -> Annotatable,
{
match self {
Annotatable::Item(i) => Annotatable::Item(f(i)),
_ => or(self),
}
}
pub fn expect_trait_item(self) -> P<ast::AssocItem> {
match self {
Annotatable::TraitItem(i) => i,
@ -1052,9 +1041,6 @@ impl<'a> ExtCtxt<'a> {
.chain(components.iter().map(|&s| Ident::with_dummy_span(s)))
.collect()
}
pub fn name_of(&self, st: &str) -> Symbol {
Symbol::intern(st)
}
pub fn check_unused_macros(&mut self) {
self.resolver.check_unused_macros();

View File

@ -139,24 +139,6 @@ impl<'a> ExtCtxt<'a> {
ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) }
}
pub fn lifetime_def(
&self,
span: Span,
ident: Ident,
attrs: Vec<ast::Attribute>,
bounds: ast::GenericBounds,
) -> ast::GenericParam {
let lifetime = self.lifetime(span, ident);
ast::GenericParam {
ident: lifetime.ident,
id: lifetime.id,
attrs: attrs.into(),
bounds,
kind: ast::GenericParamKind::Lifetime,
is_placeholder: false,
}
}
pub fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt {
ast::Stmt {
id: ast::DUMMY_NODE_ID,
@ -465,24 +447,6 @@ impl<'a> ExtCtxt<'a> {
self.pat_tuple_struct(span, path, vec![pat])
}
pub fn pat_none(&self, span: Span) -> P<ast::Pat> {
let some = self.std_path(&[sym::option, sym::Option, sym::None]);
let path = self.path_global(span, some);
self.pat_path(span, path)
}
pub fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
let some = self.std_path(&[sym::result, sym::Result, sym::Ok]);
let path = self.path_global(span, some);
self.pat_tuple_struct(span, path, vec![pat])
}
pub fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
let some = self.std_path(&[sym::result, sym::Result, sym::Err]);
let path = self.path_global(span, some);
self.pat_tuple_struct(span, path, vec![pat])
}
pub fn arm(&self, span: Span, pat: P<ast::Pat>, expr: P<ast::Expr>) -> ast::Arm {
ast::Arm {
attrs: vec![],
@ -514,26 +478,6 @@ impl<'a> ExtCtxt<'a> {
self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els))
}
pub fn lambda_fn_decl(
&self,
span: Span,
fn_decl: P<ast::FnDecl>,
body: P<ast::Expr>,
fn_decl_span: Span,
) -> P<ast::Expr> {
self.expr(
span,
ast::ExprKind::Closure(
ast::CaptureBy::Ref,
ast::Async::No,
ast::Movability::Movable,
fn_decl,
body,
fn_decl_span,
),
)
}
pub fn lambda(&self, span: Span, ids: Vec<Ident>, body: P<ast::Expr>) -> P<ast::Expr> {
let fn_decl = self.fn_decl(
ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(),
@ -610,47 +554,6 @@ impl<'a> ExtCtxt<'a> {
})
}
pub fn variant(&self, span: Span, ident: Ident, tys: Vec<P<ast::Ty>>) -> ast::Variant {
let vis_span = span.shrink_to_lo();
let fields: Vec<_> = tys
.into_iter()
.map(|ty| ast::StructField {
span: ty.span,
ty,
ident: None,
vis: ast::Visibility {
span: vis_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
attrs: Vec::new(),
id: ast::DUMMY_NODE_ID,
is_placeholder: false,
})
.collect();
let vdata = if fields.is_empty() {
ast::VariantData::Unit(ast::DUMMY_NODE_ID)
} else {
ast::VariantData::Tuple(fields, ast::DUMMY_NODE_ID)
};
ast::Variant {
attrs: Vec::new(),
data: vdata,
disr_expr: None,
id: ast::DUMMY_NODE_ID,
ident,
vis: ast::Visibility {
span: vis_span,
kind: ast::VisibilityKind::Inherited,
tokens: None,
},
span,
is_placeholder: false,
}
}
pub fn item_static(
&self,
span: Span,

View File

@ -75,33 +75,6 @@ pub fn link_or_copy<P: AsRef<Path>, Q: AsRef<Path>>(p: P, q: Q) -> io::Result<Li
}
}
#[derive(Debug)]
pub enum RenameOrCopyRemove {
Rename,
CopyRemove,
}
/// Rename `p` into `q`, preferring to use `rename` if possible.
/// If `rename` fails (rename may fail for reasons such as crossing
/// filesystem), fallback to copy & remove
pub fn rename_or_copy_remove<P: AsRef<Path>, Q: AsRef<Path>>(
p: P,
q: Q,
) -> io::Result<RenameOrCopyRemove> {
let p = p.as_ref();
let q = q.as_ref();
match fs::rename(p, q) {
Ok(()) => Ok(RenameOrCopyRemove::Rename),
Err(_) => match fs::copy(p, q) {
Ok(_) => {
fs::remove_file(p)?;
Ok(RenameOrCopyRemove::CopyRemove)
}
Err(e) => Err(e),
},
}
}
#[cfg(unix)]
pub fn path_to_c_string(p: &Path) -> CString {
use std::ffi::OsStr;

View File

@ -188,10 +188,6 @@ pub struct DefPath {
}
impl DefPath {
pub fn is_local(&self) -> bool {
self.krate == LOCAL_CRATE
}
pub fn make<FN>(krate: CrateNum, start_index: DefIndex, mut get_key: FN) -> DefPath
where
FN: FnMut(DefIndex) -> DefKey,

View File

@ -3,7 +3,6 @@ use crate::def_id::DefId;
crate use crate::hir_id::HirId;
use crate::{itemlikevisit, LangItem};
use rustc_ast::node_id::NodeMap;
use rustc_ast::util::parser::ExprPrecedence;
use rustc_ast::{self as ast, CrateSugar, LlvmAsmDialect};
use rustc_ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy};
@ -306,10 +305,6 @@ impl GenericArgs<'_> {
Self { args: &[], bindings: &[], parenthesized: false }
}
pub fn is_empty(&self) -> bool {
self.args.is_empty() && self.bindings.is_empty() && !self.parenthesized
}
pub fn inputs(&self) -> &[Ty<'_>] {
if self.parenthesized {
for arg in self.args {
@ -467,23 +462,6 @@ impl Generics<'hir> {
}
}
pub fn own_counts(&self) -> GenericParamCount {
// We could cache this as a property of `GenericParamCount`, but
// the aim is to refactor this away entirely eventually and the
// presence of this method will be a constant reminder.
let mut own_counts: GenericParamCount = Default::default();
for param in self.params {
match param.kind {
GenericParamKind::Lifetime { .. } => own_counts.lifetimes += 1,
GenericParamKind::Type { .. } => own_counts.types += 1,
GenericParamKind::Const { .. } => own_counts.consts += 1,
};
}
own_counts
}
pub fn get_named(&self, name: Symbol) -> Option<&GenericParam<'_>> {
for param in self.params {
if name == param.name.ident().name {
@ -2679,8 +2657,6 @@ pub struct Upvar {
pub span: Span,
}
pub type CaptureModeMap = NodeMap<CaptureBy>;
// The TraitCandidate's import_ids is empty if the trait is defined in the same module, and
// has length > 0 if the trait is found through an chain of imports, starting with the
// import/use statement in the scope where the trait is used.
@ -2766,32 +2742,4 @@ impl<'hir> Node<'hir> {
_ => None,
}
}
pub fn hir_id(&self) -> Option<HirId> {
match self {
Node::Item(Item { hir_id, .. })
| Node::ForeignItem(ForeignItem { hir_id, .. })
| Node::TraitItem(TraitItem { hir_id, .. })
| Node::ImplItem(ImplItem { hir_id, .. })
| Node::Field(StructField { hir_id, .. })
| Node::AnonConst(AnonConst { hir_id, .. })
| Node::Expr(Expr { hir_id, .. })
| Node::Stmt(Stmt { hir_id, .. })
| Node::Ty(Ty { hir_id, .. })
| Node::Binding(Pat { hir_id, .. })
| Node::Pat(Pat { hir_id, .. })
| Node::Arm(Arm { hir_id, .. })
| Node::Block(Block { hir_id, .. })
| Node::Local(Local { hir_id, .. })
| Node::MacroDef(MacroDef { hir_id, .. })
| Node::Lifetime(Lifetime { hir_id, .. })
| Node::Param(Param { hir_id, .. })
| Node::GenericParam(GenericParam { hir_id, .. }) => Some(*hir_id),
Node::TraitRef(TraitRef { hir_ref_id, .. }) => Some(*hir_ref_id),
Node::PathSegment(PathSegment { hir_id, .. }) => *hir_id,
Node::Variant(Variant { id, .. }) => Some(*id),
Node::Ctor(variant) => variant.ctor_hir_id(),
Node::Crate(_) | Node::Visibility(_) => None,
}
}
}

View File

@ -45,5 +45,3 @@ pub const CRATE_HIR_ID: HirId = HirId {
owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
local_id: ItemLocalId::from_u32(0),
};
pub const DUMMY_ITEM_LOCAL_ID: ItemLocalId = ItemLocalId::MAX;

View File

@ -58,25 +58,6 @@ impl<T: ExactSizeIterator> EnumerateAndAdjustIterator for T {
}
impl hir::Pat<'_> {
pub fn is_refutable(&self) -> bool {
match self.kind {
PatKind::Lit(_)
| PatKind::Range(..)
| PatKind::Path(hir::QPath::Resolved(Some(..), _) | hir::QPath::TypeRelative(..)) => {
true
}
PatKind::Path(hir::QPath::Resolved(_, ref path))
| PatKind::TupleStruct(hir::QPath::Resolved(_, ref path), ..)
| PatKind::Struct(hir::QPath::Resolved(_, ref path), ..) => match path.res {
Res::Def(DefKind::Variant, _) => true,
_ => false,
},
PatKind::Slice(..) => true,
_ => false,
}
}
/// Call `f` on every "binding" in a pattern, e.g., on `a` in
/// `match foo() { Some(a) => (), None => () }`
pub fn each_binding(&self, mut f: impl FnMut(hir::BindingAnnotation, HirId, Span, Ident)) {
@ -117,15 +98,6 @@ impl hir::Pat<'_> {
})
}
/// Checks if the pattern contains any patterns that bind something to
/// an ident or wildcard, e.g., `foo`, or `Foo(_)`, `foo @ Bar(..)`,
pub fn contains_bindings_or_wild(&self) -> bool {
self.satisfies(|p| match p.kind {
PatKind::Binding(..) | PatKind::Wild => true,
_ => false,
})
}
/// Checks if the pattern satisfies the given predicate on some sub-pattern.
fn satisfies(&self, pred: impl Fn(&hir::Pat<'_>) -> bool) -> bool {
let mut satisfies = false;

View File

@ -44,9 +44,6 @@ pub trait PpAnn {
fn nested(&self, _state: &mut State<'_>, _nested: Nested) {}
fn pre(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {}
fn post(&self, _state: &mut State<'_>, _node: AnnNode<'_>) {}
fn try_fetch_item(&self, _: hir::HirId) -> Option<&hir::Item<'_>> {
None
}
}
pub struct NoAnn;
@ -54,9 +51,6 @@ impl PpAnn for NoAnn {}
pub const NO_ANN: &dyn PpAnn = &NoAnn;
impl PpAnn for hir::Crate<'_> {
fn try_fetch_item(&self, item: hir::HirId) -> Option<&hir::Item<'_>> {
Some(self.item(item))
}
fn nested(&self, state: &mut State<'_>, nested: Nested) {
match nested {
Nested::Item(id) => state.print_item(self.item(id.id)),

View File

@ -113,13 +113,6 @@ impl Default for RegionckMode {
}
impl RegionckMode {
pub fn suppressed(self) -> bool {
match self {
Self::Solve => false,
Self::Erase { suppress_errors } => suppress_errors,
}
}
/// Indicates that the MIR borrowck will repeat these region
/// checks, so we should ignore errors if NLL is (unconditionally)
/// enabled.
@ -420,15 +413,6 @@ pub enum SubregionOrigin<'tcx> {
#[cfg(target_arch = "x86_64")]
static_assert_size!(SubregionOrigin<'_>, 32);
/// Places that type/region parameters can appear.
#[derive(Clone, Copy, Debug)]
pub enum ParameterOrigin {
Path, // foo::bar
MethodCall, // foo.bar() <-- parameters on impl providing bar()
OverloadedOperator, // a + b when overloaded
OverloadedDeref, // *a when overloaded
}
/// Times when we replace late-bound regions with variables:
#[derive(Clone, Copy, Debug)]
pub enum LateBoundRegionConversionTime {
@ -508,21 +492,6 @@ pub enum NLLRegionVariableOrigin {
},
}
impl NLLRegionVariableOrigin {
pub fn is_universal(self) -> bool {
match self {
NLLRegionVariableOrigin::FreeRegion => true,
NLLRegionVariableOrigin::Placeholder(..) => true,
NLLRegionVariableOrigin::Existential { .. } => false,
NLLRegionVariableOrigin::RootEmptyRegion => false,
}
}
pub fn is_existential(self) -> bool {
!self.is_universal()
}
}
// FIXME(eddyb) investigate overlap between this and `TyOrConstInferVar`.
#[derive(Copy, Clone, Debug)]
pub enum FixupError<'tcx> {

View File

@ -28,7 +28,6 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_middle::ty::error::TypeError;
use rustc_middle::ty::fold::{TypeFoldable, TypeVisitor};
use rustc_middle::ty::relate::{self, Relate, RelateResult, TypeRelation};
use rustc_middle::ty::subst::GenericArg;
use rustc_middle::ty::{self, InferConst, Ty, TyCtxt};
use std::fmt::Debug;
@ -119,12 +118,6 @@ pub trait TypeRelatingDelegate<'tcx> {
fn forbid_inference_vars() -> bool;
}
#[derive(Clone, Debug)]
struct ScopesAndKind<'tcx> {
scopes: Vec<BoundRegionScope<'tcx>>,
kind: GenericArg<'tcx>,
}
#[derive(Clone, Debug, Default)]
struct BoundRegionScope<'tcx> {
map: FxHashMap<ty::BoundRegion, ty::Region<'tcx>>,

View File

@ -59,9 +59,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
#[cfg(target_arch = "x86_64")]
static_assert_size!(PredicateObligation<'_>, 32);
pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
pub type TraitObligations<'tcx> = Vec<TraitObligation<'tcx>>;
pub type Selection<'tcx> = ImplSource<'tcx, PredicateObligation<'tcx>>;

View File

@ -711,10 +711,6 @@ impl<'tcx> LateContext<'tcx> {
}
}
pub fn current_lint_root(&self) -> hir::HirId {
self.last_node_with_lint_attrs
}
/// Check if a `DefId`'s path matches the given absolute type path usage.
///
/// Anonymous scopes such as `extern` imports are matched with `kw::Invalid`;

View File

@ -313,27 +313,6 @@ impl<'a, 'tcx> TyDecoder<'tcx> for DecodeContext<'a, 'tcx> {
Ok(ty)
}
fn cached_predicate_for_shorthand<F>(
&mut self,
shorthand: usize,
or_insert_with: F,
) -> Result<ty::Predicate<'tcx>, Self::Error>
where
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>,
{
let tcx = self.tcx();
let key = ty::CReaderCacheKey { cnum: self.cdata().cnum, pos: shorthand };
if let Some(&pred) = tcx.pred_rcache.borrow().get(&key) {
return Ok(pred);
}
let pred = or_insert_with(self)?;
tcx.pred_rcache.borrow_mut().insert(key, pred);
Ok(pred)
}
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
where
F: FnOnce(&mut Self) -> R,

View File

@ -3,7 +3,6 @@
//! which are available for use externally when compiled as a library.
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::def_id::DefIdSet;
use rustc_hir::HirId;
use rustc_macros::HashStable;
use std::fmt;
@ -59,7 +58,3 @@ impl<Id: Hash + Eq + fmt::Debug> fmt::Debug for AccessLevels<Id> {
fmt::Debug::fmt(&self.map, f)
}
}
/// A set containing all exported definitions from external crates.
/// The set does not contain any entries from local crates.
pub type ExternalExports = DefIdSet;

View File

@ -56,15 +56,6 @@ impl<'tcx> ConstValue<'tcx> {
}
}
pub fn try_to_str_slice(&self) -> Option<&'tcx str> {
if let ConstValue::Slice { data, start, end } = *self {
std::str::from_utf8(data.inspect_with_uninit_and_ptr_outside_interpreter(start..end))
.ok()
} else {
None
}
}
pub fn try_to_bits(&self, size: Size) -> Option<u128> {
self.try_to_scalar()?.to_bits(size).ok()
}

View File

@ -3,7 +3,7 @@
//! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
use crate::mir::coverage::{CodeRegion, CoverageKind};
use crate::mir::interpret::{Allocation, ConstValue, GlobalAlloc, Scalar};
use crate::mir::interpret::{Allocation, GlobalAlloc, Scalar};
use crate::mir::visit::MirVisitable;
use crate::ty::adjustment::PointerCast;
use crate::ty::codec::{TyDecoder, TyEncoder};
@ -460,17 +460,6 @@ impl<'tcx> Body<'tcx> {
}
}
/// Checks if `sub` is a sub scope of `sup`
pub fn is_sub_scope(&self, mut sub: SourceScope, sup: SourceScope) -> bool {
while sub != sup {
match self.source_scopes[sub].parent_scope {
None => return false,
Some(p) => sub = p,
}
}
true
}
/// Returns the return type; it always return first element from `local_decls` array.
#[inline]
pub fn return_ty(&self) -> Ty<'tcx> {
@ -1978,45 +1967,6 @@ impl<'tcx> Operand<'tcx> {
})
}
/// Convenience helper to make a `Scalar` from the given `Operand`, assuming that `Operand`
/// wraps a constant literal value. Panics if this is not the case.
pub fn scalar_from_const(operand: &Operand<'tcx>) -> Scalar {
match operand {
Operand::Constant(constant) => match constant.literal.val.try_to_scalar() {
Some(scalar) => scalar,
_ => panic!("{:?}: Scalar value expected", constant.literal.val),
},
_ => panic!("{:?}: Constant expected", operand),
}
}
/// Convenience helper to make a literal-like constant from a given `&str` slice.
/// Since this is used to synthesize MIR, assumes `user_ty` is None.
pub fn const_from_str(tcx: TyCtxt<'tcx>, val: &str, span: Span) -> Operand<'tcx> {
let tcx = tcx;
let allocation = Allocation::from_byte_aligned_bytes(val.as_bytes());
let allocation = tcx.intern_const_alloc(allocation);
let const_val = ConstValue::Slice { data: allocation, start: 0, end: val.len() };
let ty = tcx.mk_imm_ref(tcx.lifetimes.re_erased, tcx.types.str_);
Operand::Constant(box Constant {
span,
user_ty: None,
literal: ty::Const::from_value(tcx, const_val, ty),
})
}
/// Convenience helper to make a `ConstValue` from the given `Operand`, assuming that `Operand`
/// wraps a constant value (such as a `&str` slice). Panics if this is not the case.
pub fn value_from_const(operand: &Operand<'tcx>) -> ConstValue<'tcx> {
match operand {
Operand::Constant(constant) => match constant.literal.val.try_to_value() {
Some(const_value) => const_value,
_ => panic!("{:?}: ConstValue expected", constant.literal.val),
},
_ => panic!("{:?}: Constant expected", operand),
}
}
pub fn to_copy(&self) -> Self {
match *self {
Operand::Copy(_) | Operand::Constant(_) => self.clone(),
@ -2413,10 +2363,6 @@ impl<'tcx> UserTypeProjections {
self.contents.is_empty()
}
pub fn from_projections(projs: impl Iterator<Item = (UserTypeProjection, Span)>) -> Self {
UserTypeProjections { contents: projs.collect() }
}
pub fn projections_and_spans(
&self,
) -> impl Iterator<Item = &(UserTypeProjection, Span)> + ExactSizeIterator {

View File

@ -413,18 +413,6 @@ pub struct CoverageInfo {
/// For more information on why this is needed, consider looking
/// at the docs for `WithOptConstParam` itself.
impl<'tcx> TyCtxt<'tcx> {
#[inline]
pub fn mir_borrowck_opt_const_arg(
self,
def: ty::WithOptConstParam<LocalDefId>,
) -> &'tcx BorrowCheckResult<'tcx> {
if let Some(param_did) = def.const_param_did {
self.mir_borrowck_const_arg((def.did, param_did))
} else {
self.mir_borrowck(def.did)
}
}
#[inline]
pub fn mir_const_qualif_opt_const_arg(
self,

View File

@ -1186,16 +1186,6 @@ impl PlaceContext {
)
}
/// Returns `true` if this place context represents a storage live marker.
pub fn is_storage_live_marker(&self) -> bool {
matches!(self, PlaceContext::NonUse(NonUseContext::StorageLive))
}
/// Returns `true` if this place context represents a storage dead marker.
pub fn is_storage_dead_marker(&self) -> bool {
matches!(self, PlaceContext::NonUse(NonUseContext::StorageDead))
}
/// Returns `true` if this place context represents a use that potentially changes the value.
pub fn is_mutating_use(&self) -> bool {
matches!(self, PlaceContext::MutatingUse(..))

View File

@ -182,14 +182,6 @@ pub trait TyDecoder<'tcx>: Decoder {
where
F: FnOnce(&mut Self) -> Result<Ty<'tcx>, Self::Error>;
fn cached_predicate_for_shorthand<F>(
&mut self,
shorthand: usize,
or_insert_with: F,
) -> Result<ty::Predicate<'tcx>, Self::Error>
where
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>;
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
where
F: FnOnce(&mut Self) -> R;

View File

@ -534,10 +534,6 @@ impl<'tcx> TypeckResults<'tcx> {
self.node_type(pat.hir_id)
}
pub fn pat_ty_opt(&self, pat: &hir::Pat<'_>) -> Option<Ty<'tcx>> {
self.node_type_opt(pat.hir_id)
}
// Returns the type of an expression as a monotype.
//
// NB (1): This is the PRE-ADJUSTMENT TYPE for the expression. That is, in

View File

@ -97,9 +97,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
fn has_infer_types_or_consts(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_TY_INFER | TypeFlags::HAS_CT_INFER)
}
fn has_infer_consts(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_CT_INFER)
}
fn needs_infer(&self) -> bool {
self.has_type_flags(TypeFlags::NEEDS_INFER)
}
@ -113,9 +110,6 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone {
fn needs_subst(&self) -> bool {
self.has_type_flags(TypeFlags::NEEDS_SUBST)
}
fn has_re_placeholders(&self) -> bool {
self.has_type_flags(TypeFlags::HAS_RE_PLACEHOLDER)
}
/// "Free" regions in this context means that it has any region
/// that is not (a) erased or (b) late-bound.
fn has_free_regions(&self) -> bool {
@ -719,21 +713,15 @@ impl<'tcx> TyCtxt<'tcx> {
// vars. See comment on `shift_vars_through_binders` method in
// `subst.rs` for more details.
enum Direction {
In,
Out,
}
struct Shifter<'tcx> {
tcx: TyCtxt<'tcx>,
current_index: ty::DebruijnIndex,
amount: u32,
direction: Direction,
}
impl Shifter<'tcx> {
pub fn new(tcx: TyCtxt<'tcx>, amount: u32, direction: Direction) -> Self {
Shifter { tcx, current_index: ty::INNERMOST, amount, direction }
pub fn new(tcx: TyCtxt<'tcx>, amount: u32) -> Self {
Shifter { tcx, current_index: ty::INNERMOST, amount }
}
}
@ -755,13 +743,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
if self.amount == 0 || debruijn < self.current_index {
r
} else {
let debruijn = match self.direction {
Direction::In => debruijn.shifted_in(self.amount),
Direction::Out => {
assert!(debruijn.as_u32() >= self.amount);
debruijn.shifted_out(self.amount)
}
};
let debruijn = debruijn.shifted_in(self.amount);
let shifted = ty::ReLateBound(debruijn, br);
self.tcx.mk_region(shifted)
}
@ -776,13 +758,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
if self.amount == 0 || debruijn < self.current_index {
ty
} else {
let debruijn = match self.direction {
Direction::In => debruijn.shifted_in(self.amount),
Direction::Out => {
assert!(debruijn.as_u32() >= self.amount);
debruijn.shifted_out(self.amount)
}
};
let debruijn = debruijn.shifted_in(self.amount);
self.tcx.mk_ty(ty::Bound(debruijn, bound_ty))
}
}
@ -796,13 +772,7 @@ impl TypeFolder<'tcx> for Shifter<'tcx> {
if self.amount == 0 || debruijn < self.current_index {
ct
} else {
let debruijn = match self.direction {
Direction::In => debruijn.shifted_in(self.amount),
Direction::Out => {
assert!(debruijn.as_u32() >= self.amount);
debruijn.shifted_out(self.amount)
}
};
let debruijn = debruijn.shifted_in(self.amount);
self.tcx.mk_const(ty::Const { val: ty::ConstKind::Bound(debruijn, bound_ct), ty })
}
} else {
@ -830,16 +800,7 @@ where
{
debug!("shift_vars(value={:?}, amount={})", value, amount);
value.fold_with(&mut Shifter::new(tcx, amount, Direction::In))
}
pub fn shift_out_vars<'tcx, T>(tcx: TyCtxt<'tcx>, value: &T, amount: u32) -> T
where
T: TypeFoldable<'tcx>,
{
debug!("shift_out_vars(value={:?}, amount={})", value, amount);
value.fold_with(&mut Shifter::new(tcx, amount, Direction::Out))
value.fold_with(&mut Shifter::new(tcx, amount))
}
/// An "escaping var" is a bound var whose binder is not part of `t`. A bound var can be a

View File

@ -104,14 +104,6 @@ impl<'tcx> TyCtxt<'tcx> {
// ```
ty.uninhabited_from(self, param_env).contains(self, module)
}
pub fn is_ty_uninhabited_from_any_module(
self,
ty: Ty<'tcx>,
param_env: ty::ParamEnv<'tcx>,
) -> bool {
!ty.uninhabited_from(self, param_env).is_empty()
}
}
impl<'tcx> AdtDef {

View File

@ -7,7 +7,6 @@ pub use self::Variance::*;
use crate::hir::exports::ExportMap;
use crate::ich::StableHashingContext;
use crate::infer::canonical::Canonical;
use crate::middle::cstore::CrateStoreDyn;
use crate::middle::resolve_lifetime::ObjectLifetimeDefault;
use crate::mir::interpret::ErrorHandled;
@ -656,8 +655,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for TyS<'tcx> {
#[rustc_diagnostic_item = "Ty"]
pub type Ty<'tcx> = &'tcx TyS<'tcx>;
pub type CanonicalTy<'tcx> = Canonical<'tcx, Ty<'tcx>>;
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable)]
pub struct UpvarPath {
pub hir_id: hir::HirId,
@ -767,10 +764,6 @@ pub enum IntVarValue {
pub struct FloatVarValue(pub ast::FloatTy);
impl ty::EarlyBoundRegion {
pub fn to_bound_region(&self) -> ty::BoundRegion {
ty::BoundRegion::BrNamed(self.def_id, self.name)
}
/// Does this early bound region have a name? Early bound regions normally
/// always have names except when using anonymous lifetimes (`'_`).
pub fn has_name(&self) -> bool {
@ -821,14 +814,6 @@ impl GenericParamDef {
bug!("cannot convert a non-lifetime parameter def to an early bound region")
}
}
pub fn to_bound_region(&self) -> ty::BoundRegion {
if let GenericParamDefKind::Lifetime = self.kind {
self.to_early_bound_region_data().to_bound_region()
} else {
bug!("cannot convert a non-lifetime parameter def to an early bound region")
}
}
}
#[derive(Default)]
@ -1003,22 +988,6 @@ impl<'tcx> GenericPredicates<'tcx> {
instantiated.predicates.extend(self.predicates.iter().map(|(p, _)| p));
instantiated.spans.extend(self.predicates.iter().map(|(_, s)| s));
}
pub fn instantiate_supertrait(
&self,
tcx: TyCtxt<'tcx>,
poly_trait_ref: &ty::PolyTraitRef<'tcx>,
) -> InstantiatedPredicates<'tcx> {
assert_eq!(self.parent, None);
InstantiatedPredicates {
predicates: self
.predicates
.iter()
.map(|(pred, _)| pred.subst_supertrait(tcx, poly_trait_ref))
.collect(),
spans: self.predicates.iter().map(|(_, sp)| *sp).collect(),
}
}
}
#[derive(Debug)]
@ -1303,7 +1272,6 @@ impl<'tcx> PolyTraitPredicate<'tcx> {
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
#[derive(HashStable, TypeFoldable)]
pub struct OutlivesPredicate<A, B>(pub A, pub B); // `A: B`
pub type PolyOutlivesPredicate<A, B> = ty::Binder<OutlivesPredicate<A, B>>;
pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>;
pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>>;
pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder<RegionOutlivesPredicate<'tcx>>;

View File

@ -601,29 +601,6 @@ impl<'a, 'tcx> TyDecoder<'tcx> for CacheDecoder<'a, 'tcx> {
Ok(ty)
}
fn cached_predicate_for_shorthand<F>(
&mut self,
shorthand: usize,
or_insert_with: F,
) -> Result<ty::Predicate<'tcx>, Self::Error>
where
F: FnOnce(&mut Self) -> Result<ty::Predicate<'tcx>, Self::Error>,
{
let tcx = self.tcx();
let cache_key =
ty::CReaderCacheKey { cnum: CrateNum::ReservedForIncrCompCache, pos: shorthand };
if let Some(&pred) = tcx.pred_rcache.borrow().get(&cache_key) {
return Ok(pred);
}
let pred = or_insert_with(self)?;
// This may overwrite the entry, but it should overwrite with the same value.
tcx.pred_rcache.borrow_mut().insert_same(cache_key, pred);
Ok(pred)
}
fn with_position<F, R>(&mut self, pos: usize, f: F) -> R
where
F: FnOnce(&mut Self) -> R,

View File

@ -1,6 +1,5 @@
// Type substitutions.
use crate::infer::canonical::Canonical;
use crate::ty::codec::{TyDecoder, TyEncoder};
use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
use crate::ty::sty::{ClosureSubsts, GeneratorSubsts};
@ -648,8 +647,6 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
}
}
pub type CanonicalUserSubsts<'tcx> = Canonical<'tcx, UserSubsts<'tcx>>;
/// Stores the user-given substs to reach some fully qualified path
/// (e.g., `<T>::Item` or `<T as Trait>::Item`).
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]

View File

@ -50,7 +50,7 @@ pub(crate) fn destructure_const<'tcx>(
let (field_count, variant, down) = match val.ty.kind() {
ty::Array(_, len) => (usize::try_from(len.eval_usize(tcx, param_env)).unwrap(), None, op),
ty::Adt(def, _) if def.variants.is_empty() => {
return mir::DestructuredConst { variant: None, fields: tcx.arena.alloc_slice(&[]) };
return mir::DestructuredConst { variant: None, fields: &[] };
}
ty::Adt(def, _) => {
let variant = ecx.read_discriminant(op).unwrap().1;

View File

@ -62,15 +62,6 @@ where
let blocks = mir::traversal::reachable(body);
visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
}
pub fn visit_in_rpo_with(
&self,
body: &'mir mir::Body<'tcx>,
vis: &mut impl ResultsVisitor<'mir, 'tcx, FlowState = A::Domain>,
) {
let blocks = mir::traversal::reverse_postorder(body);
visit_results(body, blocks.map(|(bb, _)| bb), self, vis)
}
}
/// A solver for dataflow problems.

View File

@ -8,7 +8,7 @@ use super::MirPass;
use rustc_middle::mir::visit::{PlaceContext, Visitor};
use rustc_middle::mir::{
AggregateKind, BasicBlock, Body, BorrowKind, Local, Location, MirPhase, Operand, Rvalue,
Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
SourceScope, Statement, StatementKind, Terminator, TerminatorKind, VarDebugInfo,
};
use rustc_middle::ty::relate::{Relate, RelateResult, TypeRelation};
use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
@ -229,9 +229,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
}
}
fn visit_var_debug_info(&mut self, _var_debug_info: &VarDebugInfo<'tcx>) {
fn visit_var_debug_info(&mut self, var_debug_info: &VarDebugInfo<'tcx>) {
// Debuginfo can contain field projections, which count as a use of the base local. Skip
// debuginfo so that we avoid the storage liveness assertion in that case.
self.visit_source_info(&var_debug_info.source_info);
}
fn visit_operand(&mut self, operand: &Operand<'tcx>, location: Location) {
@ -432,4 +433,16 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
| TerminatorKind::GeneratorDrop => {}
}
}
fn visit_source_scope(&mut self, scope: &SourceScope) {
if self.body.source_scopes.get(*scope).is_none() {
self.tcx.sess.diagnostic().delay_span_bug(
self.body.span,
&format!(
"broken MIR in {:?} ({}):\ninvalid source scope {:?}",
self.body.source.instance, self.when, scope,
),
);
}
}
}

View File

@ -114,16 +114,6 @@ pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path, sp: Option<Spa
source_file_to_parser(sess, file_to_source_file(sess, path, sp))
}
/// Creates a new parser, returning buffered diagnostics if the file doesn't exist,
/// or from lexing the initial token stream.
pub fn maybe_new_parser_from_file<'a>(
sess: &'a ParseSess,
path: &Path,
) -> Result<Parser<'a>, Vec<Diagnostic>> {
let file = try_file_to_source_file(sess, path, None).map_err(|db| vec![db])?;
maybe_source_file_to_parser(sess, file)
}
/// Given a `source_file` and config, returns a parser.
fn source_file_to_parser(sess: &ParseSess, source_file: Lrc<SourceFile>) -> Parser<'_> {
panictry_buffer!(&sess.span_diagnostic, maybe_source_file_to_parser(sess, source_file))
@ -146,12 +136,6 @@ fn maybe_source_file_to_parser(
Ok(parser)
}
// Must preserve old name for now, because `quote!` from the *existing*
// compiler expands into it.
pub fn new_parser_from_tts(sess: &ParseSess, tts: Vec<TokenTree>) -> Parser<'_> {
stream_to_parser(sess, tts.into_iter().collect(), crate::MACRO_ARGUMENTS)
}
// Base abstractions
/// Given a session and a path and an optional span (for error reporting),

View File

@ -287,8 +287,9 @@ impl CheckAttrVisitor<'tcx> {
self.doc_alias_str_error(meta);
return false;
}
if let Some(c) =
doc_alias.chars().find(|&c| c == '"' || c == '\'' || c.is_whitespace())
if let Some(c) = doc_alias
.chars()
.find(|&c| c == '"' || c == '\'' || (c.is_whitespace() && c != ' '))
{
self.tcx
.sess
@ -302,6 +303,16 @@ impl CheckAttrVisitor<'tcx> {
.emit();
return false;
}
if doc_alias.starts_with(' ') || doc_alias.ends_with(' ') {
self.tcx
.sess
.struct_span_err(
meta.span(),
"`#[doc(alias = \"...\")]` cannot start or end with ' '",
)
.emit();
return false;
}
if let Some(err) = match target {
Target::Impl => Some("implementation block"),
Target::ForeignMod => Some("extern block"),

View File

@ -165,10 +165,6 @@ impl WorkProductId {
cgu_name.hash(&mut hasher);
WorkProductId { hash: hasher.finish() }
}
pub fn from_fingerprint(fingerprint: Fingerprint) -> WorkProductId {
WorkProductId { hash: fingerprint }
}
}
impl<HCX> HashStable<HCX> for WorkProductId {

View File

@ -402,11 +402,6 @@ impl<K: DepKind> DepGraph<K> {
self.data.as_ref().unwrap().previous.fingerprint_of(dep_node)
}
#[inline]
pub fn prev_dep_node_index_of(&self, dep_node: &DepNode<K>) -> SerializedDepNodeIndex {
self.data.as_ref().unwrap().previous.node_to_index(dep_node)
}
/// Checks whether a previous work product exists for `v` and, if
/// so, return the path that leads to it. Used to skip doing work.
pub fn previous_work_product(&self, v: &WorkProductId) -> Option<WorkProduct> {

View File

@ -1,7 +1,5 @@
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::graph::implementation::{
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
};
use rustc_data_structures::graph::implementation::{Direction, Graph, NodeIndex, INCOMING};
use super::{DepKind, DepNode};
@ -52,23 +50,8 @@ impl<K: DepKind> DepGraphQuery<K> {
}
}
/// All nodes reachable from `node`. In other words, things that
/// will have to be recomputed if `node` changes.
pub fn transitive_successors(&self, node: &DepNode<K>) -> Vec<&DepNode<K>> {
self.reachable_nodes(node, OUTGOING)
}
/// All nodes that can reach `node`.
pub fn transitive_predecessors(&self, node: &DepNode<K>) -> Vec<&DepNode<K>> {
self.reachable_nodes(node, INCOMING)
}
/// Just the outgoing edges from `node`.
pub fn immediate_successors(&self, node: &DepNode<K>) -> Vec<&DepNode<K>> {
if let Some(&index) = self.indices.get(&node) {
self.graph.successor_nodes(index).map(|s| self.graph.node_data(s)).collect()
} else {
vec![]
}
}
}

View File

@ -1586,5 +1586,3 @@ pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
handler.struct_warn(msg).emit();
}
pub type CompileResult = Result<(), ErrorReported>;

View File

@ -619,14 +619,6 @@ impl SyntaxContext {
HygieneData::with(|data| data.outer_mark(self))
}
#[inline]
pub fn outer_mark_with_data(self) -> (ExpnId, Transparency, ExpnData) {
HygieneData::with(|data| {
let (expn_id, transparency) = data.outer_mark(self);
(expn_id, transparency, data.expn_data(expn_id).clone())
})
}
pub fn dollar_crate_name(self) -> Symbol {
HygieneData::with(|data| data.syntax_context_data[self.0 as usize].dollar_crate_name)
}

View File

@ -223,12 +223,6 @@ impl FileName {
}
}
pub fn quote_expansion_source_code(src: &str) -> FileName {
let mut hasher = StableHasher::new();
src.hash(&mut hasher);
FileName::QuoteExpansion(hasher.finish())
}
pub fn macro_expansion_source_code(src: &str) -> FileName {
let mut hasher = StableHasher::new();
src.hash(&mut hasher);

View File

@ -451,15 +451,6 @@ impl SourceMap {
}
}
/// Returns a new `Span` covering the start and end `BytePos`s of the file containing the given
/// `pos`. This can be used to quickly determine if another `BytePos` or `Span` is from the same
/// file.
pub fn lookup_file_span(&self, pos: BytePos) -> Span {
let idx = self.lookup_source_file_idx(pos);
let SourceFile { start_pos, end_pos, .. } = *(*self.files.borrow().source_files)[idx];
Span::with_root_ctxt(start_pos, end_pos)
}
/// Returns `Some(span)`, a union of the LHS and RHS span. The LHS must precede the RHS. If
/// there are gaps between LHS and RHS, the resulting union will cross these gaps.
/// For this to work,

View File

@ -290,10 +290,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
self.infcx.tcx
}
pub fn closure_typer(&self) -> &'cx InferCtxt<'cx, 'tcx> {
self.infcx
}
///////////////////////////////////////////////////////////////////////////
// Selection
//

View File

@ -125,6 +125,7 @@ Subcommands:
dist Build distribution artifacts
install Install distribution artifacts
run, r Run tools contained in this repository
setup Create a config.toml (making it easier to use `x.py` itself)
To learn more about a subcommand, run `./x.py <subcommand> -h`",
);
@ -472,15 +473,21 @@ Arguments:
);
}
"setup" => {
subcommand_help.push_str(
subcommand_help.push_str(&format!(
"\n
x.py setup creates a `config.toml` which changes the defaults for x.py itself.
Arguments:
This subcommand accepts a 'profile' to use for builds. For example:
./x.py setup library
The profile is optional and you will be prompted interactively if it is not given.",
);
The profile is optional and you will be prompted interactively if it is not given.
The following profiles are available:
{}",
Profile::all_for_help(" ").trim_end()
));
}
_ => {}
};
@ -551,9 +558,7 @@ Arguments:
profile_string.parse().unwrap_or_else(|err| {
eprintln!("error: {}", err);
eprintln!("help: the available profiles are:");
for choice in Profile::all() {
eprintln!("- {}", choice);
}
eprint!("{}", Profile::all_for_help("- "));
std::process::exit(1);
})
} else {

View File

@ -1,4 +1,5 @@
use crate::{t, VERSION};
use std::fmt::Write as _;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use std::{
@ -20,7 +21,28 @@ impl Profile {
}
pub fn all() -> impl Iterator<Item = Self> {
[Profile::Compiler, Profile::Codegen, Profile::Library, Profile::User].iter().copied()
use Profile::*;
// N.B. these are ordered by how they are displayed, not alphabetically
[Library, Compiler, Codegen, User].iter().copied()
}
pub fn purpose(&self) -> String {
use Profile::*;
match self {
Library => "Contribute to the standard library",
Compiler => "Contribute to the compiler or rustdoc",
Codegen => "Contribute to the compiler, and also modify LLVM or codegen",
User => "Install Rust from source",
}
.to_string()
}
pub fn all_for_help(indent: &str) -> String {
let mut out = String::new();
for choice in Profile::all() {
writeln!(&mut out, "{}{}: {}", indent, choice, choice.purpose()).unwrap();
}
out
}
}
@ -29,10 +51,10 @@ impl FromStr for Profile {
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"a" | "lib" | "library" => Ok(Profile::Library),
"b" | "compiler" | "rustdoc" => Ok(Profile::Compiler),
"c" | "llvm" | "codegen" => Ok(Profile::Codegen),
"d" | "maintainer" | "user" => Ok(Profile::User),
"lib" | "library" => Ok(Profile::Library),
"compiler" | "rustdoc" => Ok(Profile::Compiler),
"llvm" | "codegen" => Ok(Profile::Codegen),
"maintainer" | "user" => Ok(Profile::User),
_ => Err(format!("unknown profile: '{}'", s)),
}
}
@ -104,19 +126,37 @@ pub fn setup(src_path: &Path, profile: Profile) {
// Used to get the path for `Subcommand::Setup`
pub fn interactive_path() -> io::Result<Profile> {
let mut input = String::new();
println!(
"Welcome to the Rust project! What do you want to do with x.py?
a) Contribute to the standard library
b) Contribute to the compiler or rustdoc
c) Contribute to the compiler, and also modify LLVM or codegen
d) Install Rust from source"
);
fn abbrev_all() -> impl Iterator<Item = (String, Profile)> {
('a'..).map(|c| c.to_string()).zip(Profile::all())
}
fn parse_with_abbrev(input: &str) -> Result<Profile, String> {
let input = input.trim().to_lowercase();
for (letter, profile) in abbrev_all() {
if input == letter {
return Ok(profile);
}
}
input.parse()
}
println!("Welcome to the Rust project! What do you want to do with x.py?");
for (letter, profile) in abbrev_all() {
println!("{}) {}: {}", letter, profile, profile.purpose());
}
let template = loop {
print!("Please choose one (a/b/c/d): ");
print!(
"Please choose one ({}): ",
abbrev_all().map(|(l, _)| l).collect::<Vec<_>>().join("/")
);
io::stdout().flush()?;
let mut input = String::new();
io::stdin().read_line(&mut input)?;
break match input.trim().to_lowercase().parse() {
if input == "" {
eprintln!("EOF on stdin, when expecting answer to question. Giving up.");
std::process::exit(1);
}
break match parse_with_abbrev(&input) {
Ok(profile) => profile,
Err(err) => {
println!("error: {}", err);

@ -1 +1 @@
Subproject commit cb28dee95e5e50b793e6ba9291c5d1568d3ad72e
Subproject commit 451a1e30f2dd137aa04e142414eafb8d05f87f84

@ -1 +1 @@
Subproject commit dd310616308e01f6cf227f46347b744aa56b77d9
Subproject commit 79ab7776929c66db83203397958fa7037d5d9a30

@ -1 +1 @@
Subproject commit 56a13c082ee90736c08d6abdcd90462517b703d3
Subproject commit 1b78182e71709169dc0f1c3acdc4541b6860e1c4

@ -1 +1 @@
Subproject commit 7d3ff1c12db08a847a57a054be4a7951ce532d2d
Subproject commit 152475937a8d8a1f508d8eeb57db79139bc803d9

View File

@ -0,0 +1,31 @@
# `codegen-backend`
The tracking issue for this feature is: [#77933](https://github.com/rust-lang/rust/issues/77933).
------------------------
This feature allows you to specify a path to a dynamic library to use as rustc's
code generation backend at runtime.
Set the `-Zcodegen-backend=<path>` compiler flag to specify the location of the
backend. The library must be of crate type `dylib` and must contain a function
named `__rustc_codegen_backend` with a signature of `fn() -> Box<dyn rustc_codegen_ssa::traits::CodegenBackend>`.
## Example
See also the [`hotplug_codegen_backend`](https://github.com/rust-lang/rust/tree/master/src/test/run-make-fulldeps/hotplug_codegen_backend) test
for a full example.
```rust,ignore
use rustc_codegen_ssa::traits::CodegenBackend;
struct MyBackend;
impl CodegenBackend for MyBackend {
// Implement codegen methods
}
#[no_mangle]
pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
Box::new(MyBackend)
}
```

View File

@ -7,6 +7,8 @@ use core::ops::Range;
use pulldown_cmark::{Event, Parser};
use rustc_feature::UnstableFeatures;
use rustc_session::lint;
use std::iter::Peekable;
use std::str::CharIndices;
pub const CHECK_INVALID_HTML_TAGS: Pass = Pass {
name: "check-invalid-html-tags",
@ -75,70 +77,97 @@ fn drop_tag(
}
}
fn extract_tag(
fn extract_html_tag(
tags: &mut Vec<(String, Range<usize>)>,
text: &str,
range: &Range<usize>,
start_pos: usize,
iter: &mut Peekable<CharIndices<'_>>,
f: &impl Fn(&str, &Range<usize>),
) {
let mut tag_name = String::new();
let mut is_closing = false;
let mut prev_pos = start_pos;
loop {
let (pos, c) = match iter.peek() {
Some((pos, c)) => (*pos, *c),
// In case we reached the of the doc comment, we want to check that it's an
// unclosed HTML tag. For example "/// <h3".
None => (prev_pos, '\0'),
};
prev_pos = pos;
// Checking if this is a closing tag (like `</a>` for `<a>`).
if c == '/' && tag_name.is_empty() {
is_closing = true;
} else if c.is_ascii_alphanumeric() {
tag_name.push(c);
} else {
if !tag_name.is_empty() {
let mut r = Range { start: range.start + start_pos, end: range.start + pos };
if c == '>' {
// In case we have a tag without attribute, we can consider the span to
// refer to it fully.
r.end += 1;
}
if is_closing {
// In case we have "</div >" or even "</div >".
if c != '>' {
if !c.is_whitespace() {
// It seems like it's not a valid HTML tag.
break;
}
let mut found = false;
for (new_pos, c) in text[pos..].char_indices() {
if !c.is_whitespace() {
if c == '>' {
r.end = range.start + new_pos + 1;
found = true;
}
break;
}
}
if !found {
break;
}
}
drop_tag(tags, tag_name, r, f);
} else {
tags.push((tag_name, r));
}
}
break;
}
iter.next();
}
}
fn extract_tags(
tags: &mut Vec<(String, Range<usize>)>,
text: &str,
range: Range<usize>,
is_in_comment: &mut Option<Range<usize>>,
f: &impl Fn(&str, &Range<usize>),
) {
let mut iter = text.char_indices().peekable();
while let Some((start_pos, c)) = iter.next() {
if c == '<' {
let mut tag_name = String::new();
let mut is_closing = false;
let mut prev_pos = start_pos;
loop {
let (pos, c) = match iter.peek() {
Some((pos, c)) => (*pos, *c),
// In case we reached the of the doc comment, we want to check that it's an
// unclosed HTML tag. For example "/// <h3".
None => (prev_pos, '\0'),
};
prev_pos = pos;
// Checking if this is a closing tag (like `</a>` for `<a>`).
if c == '/' && tag_name.is_empty() {
is_closing = true;
} else if c.is_ascii_alphanumeric() {
tag_name.push(c);
} else {
if !tag_name.is_empty() {
let mut r =
Range { start: range.start + start_pos, end: range.start + pos };
if c == '>' {
// In case we have a tag without attribute, we can consider the span to
// refer to it fully.
r.end += 1;
}
if is_closing {
// In case we have "</div >" or even "</div >".
if c != '>' {
if !c.is_whitespace() {
// It seems like it's not a valid HTML tag.
break;
}
let mut found = false;
for (new_pos, c) in text[pos..].char_indices() {
if !c.is_whitespace() {
if c == '>' {
r.end = range.start + new_pos + 1;
found = true;
}
break;
}
}
if !found {
break;
}
}
drop_tag(tags, tag_name, r, f);
} else {
tags.push((tag_name, r));
}
}
break;
}
if is_in_comment.is_some() {
if text[start_pos..].starts_with("-->") {
*is_in_comment = None;
}
} else if c == '<' {
if text[start_pos..].starts_with("<!--") {
// We skip the "!--" part. (Once `advance_by` is stable, might be nice to use it!)
iter.next();
iter.next();
iter.next();
*is_in_comment = Some(Range {
start: range.start + start_pos,
end: range.start + start_pos + 3,
});
} else {
extract_html_tag(tags, text, &range, start_pos, &mut iter, f);
}
}
}
@ -167,12 +196,15 @@ impl<'a, 'tcx> DocFolder for InvalidHtmlTagsLinter<'a, 'tcx> {
};
let mut tags = Vec::new();
let mut is_in_comment = None;
let p = Parser::new_ext(&dox, opts()).into_offset_iter();
for (event, range) in p {
match event {
Event::Html(text) => extract_tag(&mut tags, &text, range, &report_diag),
Event::Html(text) | Event::Text(text) => {
extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
}
_ => {}
}
}
@ -183,6 +215,10 @@ impl<'a, 'tcx> DocFolder for InvalidHtmlTagsLinter<'a, 'tcx> {
}) {
report_diag(&format!("unclosed HTML tag `{}`", tag), range);
}
if let Some(range) = is_in_comment {
report_diag("Unclosed HTML comment", &range);
}
}
self.fold_item_recur(item)

View File

@ -0,0 +1,19 @@
// exact-check
const QUERY = [
'Demon Lord',
];
const EXPECTED = [
{
'others': [
{
'path': 'doc_alias_whitespace',
'name': 'Struct',
'alias': 'Demon Lord',
'href': '../doc_alias_whitespace/struct.Struct.html',
'is_alias': true
},
],
},
];

View File

@ -0,0 +1,4 @@
#![feature(doc_alias)]
#[doc(alias = "Demon Lord")]
pub struct Struct;

View File

@ -11,6 +11,7 @@ pub struct Bar;
#[doc(alias = "\n")] //~ ERROR
#[doc(alias = "
")] //~^ ERROR
#[doc(alias = " ")] //~ ERROR
#[doc(alias = "\t")] //~ ERROR
#[doc(alias = " hello")] //~ ERROR
#[doc(alias = "hello ")] //~ ERROR
pub struct Foo;

View File

@ -36,17 +36,23 @@ LL | #[doc(alias = "
LL | | ")]
| |_^
error: ' ' character isn't allowed in `#[doc(alias = "...")]`
--> $DIR/check-doc-alias-attr.rs:14:7
|
LL | #[doc(alias = " ")]
| ^^^^^^^^^^^
error: '\t' character isn't allowed in `#[doc(alias = "...")]`
--> $DIR/check-doc-alias-attr.rs:15:7
--> $DIR/check-doc-alias-attr.rs:14:7
|
LL | #[doc(alias = "\t")]
| ^^^^^^^^^^^^
error: aborting due to 8 previous errors
error: `#[doc(alias = "...")]` cannot start or end with ' '
--> $DIR/check-doc-alias-attr.rs:15:7
|
LL | #[doc(alias = " hello")]
| ^^^^^^^^^^^^^^^^
error: `#[doc(alias = "...")]` cannot start or end with ' '
--> $DIR/check-doc-alias-attr.rs:16:7
|
LL | #[doc(alias = "hello ")]
| ^^^^^^^^^^^^^^^^
error: aborting due to 9 previous errors

View File

@ -73,3 +73,17 @@ pub fn e() {}
/// <div></div
//~^ ERROR unclosed HTML tag `div`
pub fn f() {}
/// <!---->
/// <!-- -->
/// <!-- <div> -->
/// <!-- <!-- -->
pub fn g() {}
/// <!--
/// -->
pub fn h() {}
/// <!--
//~^ ERROR Unclosed HTML comment
pub fn i() {}

View File

@ -76,5 +76,11 @@ error: unclosed HTML tag `div`
LL | /// <div></div
| ^^^^^
error: aborting due to 12 previous errors
error: Unclosed HTML comment
--> $DIR/invalid-html-tags.rs:87:5
|
LL | /// <!--
| ^^^
error: aborting due to 13 previous errors

View File

@ -11,6 +11,7 @@ pub struct Bar;
#[doc(alias = "\n")] //~ ERROR
#[doc(alias = "
")] //~^ ERROR
#[doc(alias = " ")] //~ ERROR
#[doc(alias = "\t")] //~ ERROR
#[doc(alias = " hello")] //~ ERROR
#[doc(alias = "hello ")] //~ ERROR
pub struct Foo;

View File

@ -36,17 +36,23 @@ LL | #[doc(alias = "
LL | | ")]
| |_^
error: ' ' character isn't allowed in `#[doc(alias = "...")]`
--> $DIR/check-doc-alias-attr.rs:14:7
|
LL | #[doc(alias = " ")]
| ^^^^^^^^^^^
error: '\t' character isn't allowed in `#[doc(alias = "...")]`
--> $DIR/check-doc-alias-attr.rs:15:7
--> $DIR/check-doc-alias-attr.rs:14:7
|
LL | #[doc(alias = "\t")]
| ^^^^^^^^^^^^
error: aborting due to 8 previous errors
error: `#[doc(alias = "...")]` cannot start or end with ' '
--> $DIR/check-doc-alias-attr.rs:15:7
|
LL | #[doc(alias = " hello")]
| ^^^^^^^^^^^^^^^^
error: `#[doc(alias = "...")]` cannot start or end with ' '
--> $DIR/check-doc-alias-attr.rs:16:7
|
LL | #[doc(alias = "hello ")]
| ^^^^^^^^^^^^^^^^
error: aborting due to 9 previous errors

View File

@ -23,6 +23,7 @@ use std::time::Instant;
static HOSTS: &[&str] = &[
"aarch64-apple-darwin",
"aarch64-pc-windows-msvc",
"aarch64-unknown-linux-gnu",
"aarch64-unknown-linux-musl",
"arm-unknown-linux-gnueabi",