Skip to content

Rollup of 12 pull requests #140695

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
May 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
5f14568
std: get rid of `sys_common::process`
joboet Mar 27, 2025
0f81fca
Change rustc_driver dependency on stable_mir crate
celinval Apr 30, 2025
415a73e
docs: alias `limit` to `Iterator::take`, cite `[u8]::utf8_chunks` in …
ShE3py May 2, 2025
cbdd713
Implement Iterator::last for vec::IntoIter
thaliaarchi Apr 13, 2025
6621826
Implement RFC 3503: frontmatters
fee1-dead Apr 12, 2025
b796179
Created `tests/rustdoc/reexports` subfolder to limit number of files …
GuillaumeGomez May 5, 2025
099f730
Created `tests/rustdoc/source-code-pages` subfolder to limit number o…
GuillaumeGomez May 5, 2025
b374996
Created `tests/rustdoc/anchors` subfolder to limit number of files at…
GuillaumeGomez May 5, 2025
ff971d0
Created `tests/rustdoc/auto` subfolder to limit number of files at th…
GuillaumeGomez May 5, 2025
9db7de5
Created `tests/rustdoc/jump-to-def` subfolder to limit number of file…
GuillaumeGomez May 5, 2025
a00b399
Move intra-doc tests into the expected subfolder
GuillaumeGomez May 5, 2025
eee6c97
Created `tests/rustdoc/private` subfolder to limit number of files at…
GuillaumeGomez May 5, 2025
d1f4a0b
Created `tests/rustdoc/macro` subfolder to limit number of files at t…
GuillaumeGomez May 5, 2025
be71d8b
Created `tests/rustdoc/doc-cfg` subfolder to limit number of files at…
GuillaumeGomez May 5, 2025
b84f4cc
Created `tests/rustdoc/impl` subfolder to limit number of files at th…
GuillaumeGomez May 5, 2025
fa2b922
Created `tests/rustdoc/assoc` subfolder to limit number of files at t…
GuillaumeGomez May 5, 2025
4b6bc73
Created `tests/rustdoc/enum` subfolder to limit number of files at th…
GuillaumeGomez May 5, 2025
e245c3b
Move primitive rustdoc tests into the `primitive` sub folder
GuillaumeGomez May 5, 2025
e14e19a
Created `tests/rustdoc/extern` subfolder to limit number of files at …
GuillaumeGomez May 5, 2025
27e39c3
Created `tests/rustdoc/async` subfolder to limit number of files at t…
GuillaumeGomez May 5, 2025
fa6d0d1
Use more accurate ELF flags on MIPS
smrobtzz May 4, 2025
57941af
Apply suggestions from code review
smrobtzz May 5, 2025
6a7996e
Take into-account `-Zremap-path-scope` when embedding filenames
Urgau Apr 19, 2025
c0dfa44
Be a bit more relaxed about not yet constrained infer vars in closure…
compiler-errors May 5, 2025
292aea5
Update mdbook to 0.4.49
ehuss May 5, 2025
a3d5562
bootstrap: Add check/test/run steps for src/tools/coverage-dump
Zalathar Apr 22, 2025
89319f2
coverage-dump: Extract some common code to an `llvm_utils` submodule
Zalathar Apr 23, 2025
bc3f0e3
coverage-dump: Extract a common parser method for maybe-compressed bytes
Zalathar Apr 23, 2025
f1b8cd4
coverage-dump: Include filenames hash in covfun line data
Zalathar Apr 22, 2025
041b2b2
coverage-dump: Make filenames available to covfun record dumping
Zalathar Apr 24, 2025
c53a767
coverage-dump: Dump filenames instead of global file IDs (and bless)
Zalathar Apr 24, 2025
c359143
Consistent trait bounds for ExtractIf Debug impls
dtolnay Mar 15, 2025
01cbc86
Rollup merge of #139550 - Urgau:rmeta-remap-path-scope, r=nnethercote
Zalathar May 6, 2025
5ca0053
Rollup merge of #139764 - dtolnay:extractif, r=Amanieu
Zalathar May 6, 2025
d5c09b4
Rollup merge of #139773 - thaliaarchi:vec-into-iter-last, r=workingju…
Zalathar May 6, 2025
627873a
Rollup merge of #140035 - fee1-dead-contrib:push-oszwkkvmpkks, r=jiey…
Zalathar May 6, 2025
42156bd
Rollup merge of #140251 - Zalathar:coverage-dump-path, r=clubby789
Zalathar May 6, 2025
7cd7605
Rollup merge of #140393 - joboet:sys_common_process, r=thomcc
Zalathar May 6, 2025
7ea3350
Rollup merge of #140532 - celinval:chores-smir-ra, r=oli-obk
Zalathar May 6, 2025
6238555
Rollup merge of #140598 - ShE3py:iter-misc-docs, r=workingjubilee
Zalathar May 6, 2025
8e9a878
Rollup merge of #140634 - smrobtzz:mips-elf-fixes, r=workingjubilee
Zalathar May 6, 2025
d36e719
Rollup merge of #140673 - GuillaumeGomez:clean-rustdoc-tests, r=notri…
Zalathar May 6, 2025
f14b4e6
Rollup merge of #140678 - compiler-errors:dont-ice-on-infer-in-upvar,…
Zalathar May 6, 2025
546c1c2
Rollup merge of #140687 - ehuss:update-mdbook, r=jieyouxu
Zalathar May 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 2 additions & 1 deletion Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,7 @@ name = "coverage-dump"
version = "0.1.0"
dependencies = [
"anyhow",
"itertools",
"leb128",
"md-5",
"miniz_oxide 0.7.4",
Expand Down Expand Up @@ -3604,13 +3605,13 @@ dependencies = [
"rustc_query_system",
"rustc_resolve",
"rustc_session",
"rustc_smir",
"rustc_span",
"rustc_target",
"rustc_trait_selection",
"rustc_ty_utils",
"serde_json",
"shlex",
"stable_mir",
"tracing",
"windows 0.59.0",
]
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_ast_passes/src/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -514,6 +514,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
gate_all!(contracts_internals, "contract internal machinery is for internal use only");
gate_all!(where_clause_attrs, "attributes in `where` clause are unstable");
gate_all!(super_let, "`super let` is experimental");
gate_all!(frontmatter, "frontmatters are experimental");

if !visitor.features.never_patterns() {
if let Some(spans) = spans.get(&sym::never_patterns) {
Expand Down
66 changes: 41 additions & 25 deletions compiler/rustc_codegen_ssa/src/back/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,45 +270,61 @@ pub(super) fn elf_os_abi(sess: &Session) -> u8 {

pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
match architecture {
Architecture::Mips => {
let arch = match sess.target.options.cpu.as_ref() {
"mips1" => elf::EF_MIPS_ARCH_1,
"mips2" => elf::EF_MIPS_ARCH_2,
Architecture::Mips | Architecture::Mips64 | Architecture::Mips64_N32 => {
// "N32" indicates an "ILP32" data model on a 64-bit MIPS CPU
// like SPARC's "v8+", x86_64's "x32", or the watchOS "arm64_32".
let is_32bit = architecture == Architecture::Mips;
let mut e_flags = match sess.target.options.cpu.as_ref() {
"mips1" if is_32bit => elf::EF_MIPS_ARCH_1,
"mips2" if is_32bit => elf::EF_MIPS_ARCH_2,
"mips3" => elf::EF_MIPS_ARCH_3,
"mips4" => elf::EF_MIPS_ARCH_4,
"mips5" => elf::EF_MIPS_ARCH_5,
s if s.contains("r6") => elf::EF_MIPS_ARCH_32R6,
_ => elf::EF_MIPS_ARCH_32R2,
"mips32r2" if is_32bit => elf::EF_MIPS_ARCH_32R2,
"mips32r6" if is_32bit => elf::EF_MIPS_ARCH_32R6,
"mips64r2" if !is_32bit => elf::EF_MIPS_ARCH_64R2,
"mips64r6" if !is_32bit => elf::EF_MIPS_ARCH_64R6,
s if s.starts_with("mips32") && !is_32bit => {
sess.dcx().fatal(format!("invalid CPU `{}` for 64-bit MIPS target", s))
}
s if s.starts_with("mips64") && is_32bit => {
sess.dcx().fatal(format!("invalid CPU `{}` for 32-bit MIPS target", s))
}
_ if is_32bit => elf::EF_MIPS_ARCH_32R2,
_ => elf::EF_MIPS_ARCH_64R2,
};

let mut e_flags = elf::EF_MIPS_CPIC | arch;

// If the ABI is explicitly given, use it or default to O32.
match sess.target.options.llvm_abiname.to_lowercase().as_str() {
"n32" => e_flags |= elf::EF_MIPS_ABI2,
"o32" => e_flags |= elf::EF_MIPS_ABI_O32,
_ => e_flags |= elf::EF_MIPS_ABI_O32,
// If the ABI is explicitly given, use it, or default to O32 on 32-bit MIPS,
// which is the only "true" 32-bit option that LLVM supports.
match sess.target.options.llvm_abiname.as_ref() {
"o32" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32,
"n32" if !is_32bit => e_flags |= elf::EF_MIPS_ABI2,
"n64" if !is_32bit => {}
"" if is_32bit => e_flags |= elf::EF_MIPS_ABI_O32,
"" => sess.dcx().fatal("LLVM ABI must be specifed for 64-bit MIPS targets"),
s if is_32bit => {
sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 32-bit MIPS target", s))
}
s => sess.dcx().fatal(format!("invalid LLVM ABI `{}` for 64-bit MIPS target", s)),
};

if sess.target.options.relocation_model != RelocModel::Static {
e_flags |= elf::EF_MIPS_PIC;
// PIC means position-independent code. CPIC means "calls PIC".
// CPIC was mutually exclusive with PIC according to
// the SVR4 MIPS ABI https://refspecs.linuxfoundation.org/elf/mipsabi.pdf
// and should have only appeared on static objects with dynamically calls.
// At some point someone (GCC?) decided to set CPIC even for PIC.
// Nowadays various things expect both set on the same object file
// and may even error if you mix CPIC and non-CPIC object files,
// despite that being the entire point of the CPIC ABI extension!
// As we are in Rome, we do as the Romans do.
e_flags |= elf::EF_MIPS_PIC | elf::EF_MIPS_CPIC;
}
if sess.target.options.cpu.contains("r6") {
e_flags |= elf::EF_MIPS_NAN2008;
}
e_flags
}
Architecture::Mips64 => {
// copied from `mips64el-linux-gnuabi64-gcc foo.c -c`
let e_flags = elf::EF_MIPS_CPIC
| elf::EF_MIPS_PIC
| if sess.target.options.cpu.contains("r6") {
elf::EF_MIPS_ARCH_64R6 | elf::EF_MIPS_NAN2008
} else {
elf::EF_MIPS_ARCH_64R2
};
e_flags
}
Architecture::Riscv32 | Architecture::Riscv64 => {
// Source: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/blob/079772828bd10933d34121117a222b4cc0ee2200/riscv-elf.adoc
let mut e_flags: u32 = 0x0;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ rustc_privacy = { path = "../rustc_privacy" }
rustc_query_system = { path = "../rustc_query_system" }
rustc_resolve = { path = "../rustc_resolve" }
rustc_session = { path = "../rustc_session" }
rustc_smir = { path = "../rustc_smir" }
rustc_span = { path = "../rustc_span" }
rustc_target = { path = "../rustc_target" }
rustc_trait_selection = { path = "../rustc_trait_selection" }
rustc_ty_utils = { path = "../rustc_ty_utils" }
serde_json = "1.0.59"
shlex = "1.0"
stable_mir = { path = "../stable_mir", features = ["rustc_internal"] }
tracing = { version = "0.1.35" }
# tidy-alphabetical-end

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_driver_impl/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use rustc_middle::ty::{self, TyCtxt};
use rustc_mir_build::thir::print::{thir_flat, thir_tree};
use rustc_session::Session;
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
use rustc_smir::rustc_internal::pretty::write_smir_pretty;
use rustc_span::{FileName, Ident};
use stable_mir::rustc_internal::pretty::write_smir_pretty;
use tracing::debug;
use {rustc_ast as ast, rustc_hir_pretty as pprust_hir};

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_feature/src/unstable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,8 @@ declare_features! (
(incomplete, fn_delegation, "1.76.0", Some(118212)),
/// Allows impls for the Freeze trait.
(internal, freeze_impls, "1.78.0", Some(121675)),
/// Frontmatter `---` blocks for use by external tools.
(unstable, frontmatter, "CURRENT_RUSTC_VERSION", Some(136889)),
/// Allows defining gen blocks and `gen fn`.
(unstable, gen_blocks, "1.75.0", Some(117078)),
/// Infer generic args for both consts and types.
Expand Down
49 changes: 19 additions & 30 deletions compiler/rustc_hir_typeck/src/expr_use_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ pub trait TypeInformationCtxt<'tcx> {

fn resolve_vars_if_possible<T: TypeFoldable<TyCtxt<'tcx>>>(&self, t: T) -> T;

fn try_structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;
fn structurally_resolve_type(&self, span: Span, ty: Ty<'tcx>) -> Ty<'tcx>;

fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error;

Expand Down Expand Up @@ -191,8 +191,8 @@ impl<'tcx> TypeInformationCtxt<'tcx> for &FnCtxt<'_, 'tcx> {
self.infcx.resolve_vars_if_possible(t)
}

fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
(**self).try_structurally_resolve_type(sp, ty)
fn structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
(**self).structurally_resolve_type(sp, ty)
}

fn report_bug(&self, span: Span, msg: impl ToString) -> Self::Error {
Expand Down Expand Up @@ -236,7 +236,7 @@ impl<'tcx> TypeInformationCtxt<'tcx> for (&LateContext<'tcx>, LocalDefId) {
self.0.maybe_typeck_results().expect("expected typeck results")
}

fn try_structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
fn structurally_resolve_type(&self, _span: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
// FIXME: Maybe need to normalize here.
ty
}
Expand Down Expand Up @@ -776,7 +776,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx

// Select just those fields of the `with`
// expression that will actually be used
match self.cx.try_structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
match self.cx.structurally_resolve_type(with_expr.span, with_place.place.ty()).kind() {
ty::Adt(adt, args) if adt.is_struct() => {
// Consume those fields of the with expression that are needed.
for (f_index, with_field) in adt.non_enum_variant().fields.iter_enumerated() {
Expand Down Expand Up @@ -1176,7 +1176,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
/// two operations: a dereference to reach the array data and then an index to
/// jump forward to the relevant item.
impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx, Cx, D> {
fn resolve_type_vars_or_bug(
fn expect_and_resolve_type(
&self,
id: HirId,
ty: Option<Ty<'tcx>>,
Expand All @@ -1185,12 +1185,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
Some(ty) => {
let ty = self.cx.resolve_vars_if_possible(ty);
self.cx.error_reported_in_ty(ty)?;
if ty.is_ty_var() {
debug!("resolve_type_vars_or_bug: infer var from {:?}", ty);
Err(self.cx.report_bug(self.cx.tcx().hir_span(id), "encountered type variable"))
} else {
Ok(ty)
}
Ok(ty)
}
None => {
// FIXME: We shouldn't be relying on the infcx being tainted.
Expand All @@ -1201,15 +1196,15 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
}

fn node_ty(&self, hir_id: HirId) -> Result<Ty<'tcx>, Cx::Error> {
self.resolve_type_vars_or_bug(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
self.expect_and_resolve_type(hir_id, self.cx.typeck_results().node_type_opt(hir_id))
}

fn expr_ty(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
self.resolve_type_vars_or_bug(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
self.expect_and_resolve_type(expr.hir_id, self.cx.typeck_results().expr_ty_opt(expr))
}

fn expr_ty_adjusted(&self, expr: &hir::Expr<'_>) -> Result<Ty<'tcx>, Cx::Error> {
self.resolve_type_vars_or_bug(
self.expect_and_resolve_type(
expr.hir_id,
self.cx.typeck_results().expr_ty_adjusted_opt(expr),
)
Expand Down Expand Up @@ -1264,10 +1259,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
// a bind-by-ref means that the base_ty will be the type of the ident itself,
// but what we want here is the type of the underlying value being borrowed.
// So peel off one-level, turning the &T into T.
match self
.cx
.try_structurally_resolve_type(pat.span, base_ty)
.builtin_deref(false)
match self.cx.structurally_resolve_type(pat.span, base_ty).builtin_deref(false)
{
Some(ty) => Ok(ty),
None => {
Expand Down Expand Up @@ -1513,10 +1505,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
if node_ty != place_ty
&& self
.cx
.try_structurally_resolve_type(
self.cx.tcx().hir_span(base_place.hir_id),
place_ty,
)
.structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), place_ty)
.is_impl_trait()
{
projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
Expand All @@ -1538,7 +1527,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
let base_ty = self.expr_ty_adjusted(base)?;

let ty::Ref(region, _, mutbl) =
*self.cx.try_structurally_resolve_type(base.span, base_ty).kind()
*self.cx.structurally_resolve_type(base.span, base_ty).kind()
else {
span_bug!(expr.span, "cat_overloaded_place: base is not a reference");
};
Expand All @@ -1556,7 +1545,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
let base_curr_ty = base_place.place.ty();
let deref_ty = match self
.cx
.try_structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
.structurally_resolve_type(self.cx.tcx().hir_span(base_place.hir_id), base_curr_ty)
.builtin_deref(true)
{
Some(ty) => ty,
Expand Down Expand Up @@ -1584,7 +1573,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
) -> Result<VariantIdx, Cx::Error> {
let res = self.cx.typeck_results().qpath_res(qpath, pat_hir_id);
let ty = self.cx.typeck_results().node_type(pat_hir_id);
let ty::Adt(adt_def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() else {
let ty::Adt(adt_def, _) = self.cx.structurally_resolve_type(span, ty).kind() else {
return Err(self
.cx
.report_bug(span, "struct or tuple struct pattern not applied to an ADT"));
Expand Down Expand Up @@ -1616,7 +1605,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
span: Span,
) -> Result<usize, Cx::Error> {
let ty = self.cx.typeck_results().node_type(pat_hir_id);
match self.cx.try_structurally_resolve_type(span, ty).kind() {
match self.cx.structurally_resolve_type(span, ty).kind() {
ty::Adt(adt_def, _) => Ok(adt_def.variant(variant_index).fields.len()),
_ => {
self.cx
Expand All @@ -1631,7 +1620,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
/// Here `pat_hir_id` is the HirId of the pattern itself.
fn total_fields_in_tuple(&self, pat_hir_id: HirId, span: Span) -> Result<usize, Cx::Error> {
let ty = self.cx.typeck_results().node_type(pat_hir_id);
match self.cx.try_structurally_resolve_type(span, ty).kind() {
match self.cx.structurally_resolve_type(span, ty).kind() {
ty::Tuple(args) => Ok(args.len()),
_ => Err(self.cx.report_bug(span, "tuple pattern not applied to a tuple")),
}
Expand Down Expand Up @@ -1820,7 +1809,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
PatKind::Slice(before, ref slice, after) => {
let Some(element_ty) = self
.cx
.try_structurally_resolve_type(pat.span, place_with_id.place.ty())
.structurally_resolve_type(pat.span, place_with_id.place.ty())
.builtin_index()
else {
debug!("explicit index of non-indexable type {:?}", place_with_id);
Expand Down Expand Up @@ -1890,7 +1879,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
}

fn is_multivariant_adt(&self, ty: Ty<'tcx>, span: Span) -> bool {
if let ty::Adt(def, _) = self.cx.try_structurally_resolve_type(span, ty).kind() {
if let ty::Adt(def, _) = self.cx.structurally_resolve_type(span, ty).kind() {
// Note that if a non-exhaustive SingleVariant is defined in another crate, we need
// to assume that more cases will be added to the variant in the future. This mean
// that we should handle non-exhaustive SingleVariant the same way we would handle
Expand Down
14 changes: 13 additions & 1 deletion compiler/rustc_lexer/src/cursor.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use std::str::Chars;

pub enum FrontmatterAllowed {
Yes,
No,
}

/// Peekable iterator over a char sequence.
///
/// Next characters can be peeked via `first` method,
Expand All @@ -8,17 +13,19 @@ pub struct Cursor<'a> {
len_remaining: usize,
/// Iterator over chars. Slightly faster than a &str.
chars: Chars<'a>,
pub(crate) frontmatter_allowed: FrontmatterAllowed,
#[cfg(debug_assertions)]
prev: char,
}

pub(crate) const EOF_CHAR: char = '\0';

impl<'a> Cursor<'a> {
pub fn new(input: &'a str) -> Cursor<'a> {
pub fn new(input: &'a str, frontmatter_allowed: FrontmatterAllowed) -> Cursor<'a> {
Cursor {
len_remaining: input.len(),
chars: input.chars(),
frontmatter_allowed,
#[cfg(debug_assertions)]
prev: EOF_CHAR,
}
Expand Down Expand Up @@ -95,6 +102,11 @@ impl<'a> Cursor<'a> {
Some(c)
}

/// Moves to a substring by a number of bytes.
pub(crate) fn bump_bytes(&mut self, n: usize) {
self.chars = self.as_str()[n..].chars();
}

/// Eats symbols while predicate returns true or until the end of file is reached.
pub(crate) fn eat_while(&mut self, mut predicate: impl FnMut(char) -> bool) {
// It was tried making optimized version of this for eg. line comments, but
Expand Down
Loading
Loading