mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 15:23:46 +00:00
Auto merge of #69393 - Dylan-DPC:rollup-rxbd1zg, r=Dylan-DPC
Rollup of 5 pull requests Successful merges: - #69336 (Do not ping the infrastructure team on toolstate changes) - #69351 (Improve external MinGW detection) - #69361 (parse: allow `type Foo: Ord` syntactically) - #69375 (Rename CodeMap to SourceMap follow up) - #69376 (parser: Cleanup `Parser::bump_with` and its uses) Failed merges: r? @ghost
This commit is contained in:
commit
6d0e58bff8
@ -149,7 +149,7 @@ impl<'a> StableHashingContext<'a> {
|
||||
#[inline]
|
||||
pub fn source_map(&mut self) -> &mut CachingSourceMapView<'a> {
|
||||
match self.caching_source_map {
|
||||
Some(ref mut cm) => cm,
|
||||
Some(ref mut sm) => sm,
|
||||
ref mut none => {
|
||||
*none = Some(CachingSourceMapView::new(self.raw_source_map));
|
||||
none.as_mut().unwrap()
|
||||
|
@ -106,10 +106,10 @@ pub fn report_unstable(
|
||||
};
|
||||
|
||||
let msp: MultiSpan = span.into();
|
||||
let cm = &sess.parse_sess.source_map();
|
||||
let sm = &sess.parse_sess.source_map();
|
||||
let span_key = msp.primary_span().and_then(|sp: Span| {
|
||||
if !sp.is_dummy() {
|
||||
let file = cm.lookup_char_pos(sp.lo()).file;
|
||||
let file = sm.lookup_char_pos(sp.lo()).file;
|
||||
if file.name.is_macros() { None } else { Some(span) }
|
||||
} else {
|
||||
None
|
||||
|
@ -297,28 +297,28 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
|
||||
ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)),
|
||||
ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)),
|
||||
ItemKind::TyAlias(ref ty, ref generics) => match ty.kind.opaque_top_hack() {
|
||||
ItemKind::TyAlias(ref generics, _, Some(ref ty)) => match ty.kind.opaque_top_hack() {
|
||||
None => {
|
||||
let ty = self.lower_ty(ty, ImplTraitContext::disallowed());
|
||||
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
}
|
||||
Some(bounds) => {
|
||||
let ctx = || ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc);
|
||||
let ty = hir::OpaqueTy {
|
||||
generics: self.lower_generics(
|
||||
generics,
|
||||
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
|
||||
),
|
||||
bounds: self.lower_param_bounds(
|
||||
bounds,
|
||||
ImplTraitContext::OpaqueTy(None, hir::OpaqueTyOrigin::Misc),
|
||||
),
|
||||
generics: self.lower_generics(generics, ctx()),
|
||||
bounds: self.lower_param_bounds(bounds, ctx()),
|
||||
impl_trait_fn: None,
|
||||
origin: hir::OpaqueTyOrigin::TypeAlias,
|
||||
};
|
||||
hir::ItemKind::OpaqueTy(ty)
|
||||
}
|
||||
},
|
||||
ItemKind::TyAlias(ref generics, _, None) => {
|
||||
let ty = self.arena.alloc(self.ty(span, hir::TyKind::Err));
|
||||
let generics = self.lower_generics(generics, ImplTraitContext::disallowed());
|
||||
hir::ItemKind::TyAlias(ty, generics)
|
||||
}
|
||||
ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum(
|
||||
hir::EnumDef {
|
||||
variants: self.arena.alloc_from_iter(
|
||||
|
@ -462,7 +462,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
ItemKind::Struct(_, ref generics)
|
||||
| ItemKind::Union(_, ref generics)
|
||||
| ItemKind::Enum(_, ref generics)
|
||||
| ItemKind::TyAlias(_, ref generics)
|
||||
| ItemKind::TyAlias(ref generics, ..)
|
||||
| ItemKind::Trait(_, _, ref generics, ..) => {
|
||||
let def_id = self.lctx.resolver.definitions().local_def_id(item.id);
|
||||
let count = generics
|
||||
|
@ -969,6 +969,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
||||
let msg = "free static item without body";
|
||||
self.error_item_without_body(item.span, "static", msg, " = <expr>;");
|
||||
}
|
||||
ItemKind::TyAlias(_, ref bounds, ref body) => {
|
||||
if body.is_none() {
|
||||
let msg = "free type alias without body";
|
||||
self.error_item_without_body(item.span, "type", msg, " = <type>;");
|
||||
}
|
||||
self.check_type_no_bounds(bounds, "this context");
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
|
@ -372,7 +372,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
|
||||
gate_feature_post!(&self, decl_macro, i.span, msg);
|
||||
}
|
||||
|
||||
ast::ItemKind::TyAlias(ref ty, ..) => self.check_impl_trait(&ty),
|
||||
ast::ItemKind::TyAlias(_, _, Some(ref ty)) => self.check_impl_trait(&ty),
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
@ -47,15 +47,15 @@ pub struct NoAnn;
|
||||
impl PpAnn for NoAnn {}
|
||||
|
||||
pub struct Comments<'a> {
|
||||
cm: &'a SourceMap,
|
||||
sm: &'a SourceMap,
|
||||
comments: Vec<comments::Comment>,
|
||||
current: usize,
|
||||
}
|
||||
|
||||
impl<'a> Comments<'a> {
|
||||
pub fn new(cm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> {
|
||||
let comments = comments::gather_comments(cm, filename, input);
|
||||
Comments { cm, comments, current: 0 }
|
||||
pub fn new(sm: &'a SourceMap, filename: FileName, input: String) -> Comments<'a> {
|
||||
let comments = comments::gather_comments(sm, filename, input);
|
||||
Comments { sm, comments, current: 0 }
|
||||
}
|
||||
|
||||
pub fn next(&self) -> Option<comments::Comment> {
|
||||
@ -71,8 +71,8 @@ impl<'a> Comments<'a> {
|
||||
if cmnt.style != comments::Trailing {
|
||||
return None;
|
||||
}
|
||||
let span_line = self.cm.lookup_char_pos(span.hi());
|
||||
let comment_line = self.cm.lookup_char_pos(cmnt.pos);
|
||||
let span_line = self.sm.lookup_char_pos(span.hi());
|
||||
let comment_line = self.sm.lookup_char_pos(cmnt.pos);
|
||||
let next = next_pos.unwrap_or_else(|| cmnt.pos + BytePos(1));
|
||||
if span.hi() < cmnt.pos && cmnt.pos < next && span_line.line == comment_line.line {
|
||||
return Some(cmnt);
|
||||
@ -95,7 +95,7 @@ crate const INDENT_UNIT: usize = 4;
|
||||
/// Requires you to pass an input filename and reader so that
|
||||
/// it can scan the input text for comments to copy forward.
|
||||
pub fn print_crate<'a>(
|
||||
cm: &'a SourceMap,
|
||||
sm: &'a SourceMap,
|
||||
krate: &ast::Crate,
|
||||
filename: FileName,
|
||||
input: String,
|
||||
@ -106,7 +106,7 @@ pub fn print_crate<'a>(
|
||||
) -> String {
|
||||
let mut s = State {
|
||||
s: pp::mk_printer(),
|
||||
comments: Some(Comments::new(cm, filename, input)),
|
||||
comments: Some(Comments::new(sm, filename, input)),
|
||||
ann,
|
||||
is_expanded,
|
||||
};
|
||||
@ -522,8 +522,8 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
|
||||
self.hardbreak();
|
||||
}
|
||||
}
|
||||
if let Some(cm) = self.comments() {
|
||||
cm.current += 1;
|
||||
if let Some(cmnts) = self.comments() {
|
||||
cmnts.current += 1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1185,18 +1185,10 @@ impl<'a> State<'a> {
|
||||
self.s.word(ga.asm.to_string());
|
||||
self.end();
|
||||
}
|
||||
ast::ItemKind::TyAlias(ref ty, ref generics) => {
|
||||
self.head(visibility_qualified(&item.vis, "type"));
|
||||
self.print_ident(item.ident);
|
||||
self.print_generic_params(&generics.params);
|
||||
self.end(); // end the inner ibox
|
||||
|
||||
self.print_where_clause(&generics.where_clause);
|
||||
self.s.space();
|
||||
self.word_space("=");
|
||||
self.print_type(ty);
|
||||
self.s.word(";");
|
||||
self.end(); // end the outer ibox
|
||||
ast::ItemKind::TyAlias(ref generics, ref bounds, ref ty) => {
|
||||
let def = ast::Defaultness::Final;
|
||||
let ty = ty.as_deref();
|
||||
self.print_associated_type(item.ident, generics, bounds, ty, &item.vis, def);
|
||||
}
|
||||
ast::ItemKind::Enum(ref enum_definition, ref params) => {
|
||||
self.print_enum_def(enum_definition, params, item.ident, item.span, &item.vis);
|
||||
|
@ -452,8 +452,8 @@ pub fn print_after_hir_lowering<'tcx>(
|
||||
call_with_pp_support_hir(&s, tcx, move |annotation, krate| {
|
||||
debug!("pretty printing source code {:?}", s);
|
||||
let sess = annotation.sess();
|
||||
let cm = sess.source_map();
|
||||
*out = pprust_hir::print_crate(cm, krate, src_name, src, annotation.pp_ann())
|
||||
let sm = sess.source_map();
|
||||
*out = pprust_hir::print_crate(sm, krate, src_name, src, annotation.pp_ann())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -373,13 +373,13 @@ impl DiagnosticSpan {
|
||||
|
||||
impl DiagnosticSpanLine {
|
||||
fn line_from_source_file(
|
||||
fm: &rustc_span::SourceFile,
|
||||
sf: &rustc_span::SourceFile,
|
||||
index: usize,
|
||||
h_start: usize,
|
||||
h_end: usize,
|
||||
) -> DiagnosticSpanLine {
|
||||
DiagnosticSpanLine {
|
||||
text: fm.get_line(index).map_or(String::new(), |l| l.into_owned()),
|
||||
text: sf.get_line(index).map_or(String::new(), |l| l.into_owned()),
|
||||
highlight_start: h_start,
|
||||
highlight_end: h_end,
|
||||
}
|
||||
@ -392,13 +392,13 @@ impl DiagnosticSpanLine {
|
||||
je.sm
|
||||
.span_to_lines(span)
|
||||
.map(|lines| {
|
||||
let fm = &*lines.file;
|
||||
let sf = &*lines.file;
|
||||
lines
|
||||
.lines
|
||||
.iter()
|
||||
.map(|line| {
|
||||
DiagnosticSpanLine::line_from_source_file(
|
||||
fm,
|
||||
sf,
|
||||
line.line_index,
|
||||
line.start_col.0 + 1,
|
||||
line.end_col.0 + 1,
|
||||
|
@ -144,7 +144,7 @@ pub struct SubstitutionPart {
|
||||
impl CodeSuggestion {
|
||||
/// Returns the assembled code suggestions, whether they should be shown with an underline
|
||||
/// and whether the substitution only differs in capitalization.
|
||||
pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
|
||||
pub fn splice_lines(&self, sm: &SourceMap) -> Vec<(String, Vec<SubstitutionPart>, bool)> {
|
||||
use rustc_span::{CharPos, Pos};
|
||||
|
||||
fn push_trailing(
|
||||
@ -176,7 +176,7 @@ impl CodeSuggestion {
|
||||
.filter(|subst| {
|
||||
// Suggestions coming from macros can have malformed spans. This is a heavy
|
||||
// handed approach to avoid ICEs by ignoring the suggestion outright.
|
||||
let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err());
|
||||
let invalid = subst.parts.iter().any(|item| sm.is_valid_span(item.span).is_err());
|
||||
if invalid {
|
||||
debug!("splice_lines: suggestion contains an invalid span: {:?}", subst);
|
||||
}
|
||||
@ -193,7 +193,7 @@ impl CodeSuggestion {
|
||||
let hi = substitution.parts.iter().map(|part| part.span.hi()).max()?;
|
||||
let bounding_span = Span::with_root_ctxt(lo, hi);
|
||||
// The different spans might belong to different contexts, if so ignore suggestion.
|
||||
let lines = cm.span_to_lines(bounding_span).ok()?;
|
||||
let lines = sm.span_to_lines(bounding_span).ok()?;
|
||||
assert!(!lines.lines.is_empty());
|
||||
|
||||
// To build up the result, we do this for each span:
|
||||
@ -205,36 +205,36 @@ impl CodeSuggestion {
|
||||
// - splice in the span substitution
|
||||
//
|
||||
// Finally push the trailing line segment of the last span
|
||||
let fm = &lines.file;
|
||||
let mut prev_hi = cm.lookup_char_pos(bounding_span.lo());
|
||||
let sf = &lines.file;
|
||||
let mut prev_hi = sm.lookup_char_pos(bounding_span.lo());
|
||||
prev_hi.col = CharPos::from_usize(0);
|
||||
|
||||
let mut prev_line = fm.get_line(lines.lines[0].line_index);
|
||||
let mut prev_line = sf.get_line(lines.lines[0].line_index);
|
||||
let mut buf = String::new();
|
||||
|
||||
for part in &substitution.parts {
|
||||
let cur_lo = cm.lookup_char_pos(part.span.lo());
|
||||
let cur_lo = sm.lookup_char_pos(part.span.lo());
|
||||
if prev_hi.line == cur_lo.line {
|
||||
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, Some(&cur_lo));
|
||||
} else {
|
||||
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
|
||||
// push lines between the previous and current span (if any)
|
||||
for idx in prev_hi.line..(cur_lo.line - 1) {
|
||||
if let Some(line) = fm.get_line(idx) {
|
||||
if let Some(line) = sf.get_line(idx) {
|
||||
buf.push_str(line.as_ref());
|
||||
buf.push('\n');
|
||||
}
|
||||
}
|
||||
if let Some(cur_line) = fm.get_line(cur_lo.line - 1) {
|
||||
if let Some(cur_line) = sf.get_line(cur_lo.line - 1) {
|
||||
let end = std::cmp::min(cur_line.len(), cur_lo.col.to_usize());
|
||||
buf.push_str(&cur_line[..end]);
|
||||
}
|
||||
}
|
||||
buf.push_str(&part.snippet);
|
||||
prev_hi = cm.lookup_char_pos(part.span.hi());
|
||||
prev_line = fm.get_line(prev_hi.line - 1);
|
||||
prev_hi = sm.lookup_char_pos(part.span.hi());
|
||||
prev_line = sf.get_line(prev_hi.line - 1);
|
||||
}
|
||||
let only_capitalization = is_case_difference(cm, &buf, bounding_span);
|
||||
let only_capitalization = is_case_difference(sm, &buf, bounding_span);
|
||||
// if the replacement already ends with a newline, don't print the next line
|
||||
if !buf.ends_with('\n') {
|
||||
push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
|
||||
@ -363,23 +363,23 @@ impl Handler {
|
||||
color_config: ColorConfig,
|
||||
can_emit_warnings: bool,
|
||||
treat_err_as_bug: Option<usize>,
|
||||
cm: Option<Lrc<SourceMap>>,
|
||||
sm: Option<Lrc<SourceMap>>,
|
||||
) -> Self {
|
||||
Self::with_tty_emitter_and_flags(
|
||||
color_config,
|
||||
cm,
|
||||
sm,
|
||||
HandlerFlags { can_emit_warnings, treat_err_as_bug, ..Default::default() },
|
||||
)
|
||||
}
|
||||
|
||||
pub fn with_tty_emitter_and_flags(
|
||||
color_config: ColorConfig,
|
||||
cm: Option<Lrc<SourceMap>>,
|
||||
sm: Option<Lrc<SourceMap>>,
|
||||
flags: HandlerFlags,
|
||||
) -> Self {
|
||||
let emitter = Box::new(EmitterWriter::stderr(
|
||||
color_config,
|
||||
cm,
|
||||
sm,
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
|
@ -140,13 +140,13 @@ pub const INDENT_UNIT: usize = 4;
|
||||
/// Requires you to pass an input filename and reader so that
|
||||
/// it can scan the input text for comments to copy forward.
|
||||
pub fn print_crate<'a>(
|
||||
cm: &'a SourceMap,
|
||||
sm: &'a SourceMap,
|
||||
krate: &hir::Crate<'_>,
|
||||
filename: FileName,
|
||||
input: String,
|
||||
ann: &'a dyn PpAnn,
|
||||
) -> String {
|
||||
let mut s = State::new_from_input(cm, filename, input, ann);
|
||||
let mut s = State::new_from_input(sm, filename, input, ann);
|
||||
|
||||
// When printing the AST, we sometimes need to inject `#[no_std]` here.
|
||||
// Since you can't compile the HIR, it's not necessary.
|
||||
@ -158,12 +158,12 @@ pub fn print_crate<'a>(
|
||||
|
||||
impl<'a> State<'a> {
|
||||
pub fn new_from_input(
|
||||
cm: &'a SourceMap,
|
||||
sm: &'a SourceMap,
|
||||
filename: FileName,
|
||||
input: String,
|
||||
ann: &'a dyn PpAnn,
|
||||
) -> State<'a> {
|
||||
State { s: pp::mk_printer(), comments: Some(Comments::new(cm, filename, input)), ann }
|
||||
State { s: pp::mk_printer(), comments: Some(Comments::new(sm, filename, input)), ann }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ fn msg_span_from_early_bound_and_free_regions(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
region: ty::Region<'tcx>,
|
||||
) -> (String, Option<Span>) {
|
||||
let cm = tcx.sess.source_map();
|
||||
let sm = tcx.sess.source_map();
|
||||
|
||||
let scope = region.free_region_binding_scope(tcx);
|
||||
let node = tcx.hir().as_local_hir_id(scope).unwrap_or(hir::DUMMY_HIR_ID);
|
||||
@ -207,7 +207,7 @@ fn msg_span_from_early_bound_and_free_regions(
|
||||
};
|
||||
let (prefix, span) = match *region {
|
||||
ty::ReEarlyBound(ref br) => {
|
||||
let mut sp = cm.def_span(tcx.hir().span(node));
|
||||
let mut sp = sm.def_span(tcx.hir().span(node));
|
||||
if let Some(param) =
|
||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(br.name))
|
||||
{
|
||||
@ -216,7 +216,7 @@ fn msg_span_from_early_bound_and_free_regions(
|
||||
(format!("the lifetime `{}` as defined on", br.name), sp)
|
||||
}
|
||||
ty::ReFree(ty::FreeRegion { bound_region: ty::BoundRegion::BrNamed(_, name), .. }) => {
|
||||
let mut sp = cm.def_span(tcx.hir().span(node));
|
||||
let mut sp = sm.def_span(tcx.hir().span(node));
|
||||
if let Some(param) =
|
||||
tcx.hir().get_generics(scope).and_then(|generics| generics.get_named(name))
|
||||
{
|
||||
@ -230,7 +230,7 @@ fn msg_span_from_early_bound_and_free_regions(
|
||||
}
|
||||
_ => (
|
||||
format!("the lifetime `{}` as defined on", region),
|
||||
cm.def_span(tcx.hir().span(node)),
|
||||
sm.def_span(tcx.hir().span(node)),
|
||||
),
|
||||
},
|
||||
_ => bug!(),
|
||||
|
@ -1625,10 +1625,10 @@ impl<'a> Parser<'a> {
|
||||
let hi = self.token.span;
|
||||
|
||||
if require_comma {
|
||||
let cm = self.sess.source_map();
|
||||
let sm = self.sess.source_map();
|
||||
self.expect_one_of(&[token::Comma], &[token::CloseDelim(token::Brace)]).map_err(
|
||||
|mut err| {
|
||||
match (cm.span_to_lines(expr.span), cm.span_to_lines(arm_start_span)) {
|
||||
match (sm.span_to_lines(expr.span), sm.span_to_lines(arm_start_span)) {
|
||||
(Ok(ref expr_lines), Ok(ref arm_start_lines))
|
||||
if arm_start_lines.lines[0].end_col == expr_lines.lines[0].end_col
|
||||
&& expr_lines.lines.len() == 2
|
||||
|
@ -156,8 +156,7 @@ impl<'a> Parser<'a> {
|
||||
self.parse_item_mod(attrs)?
|
||||
} else if self.eat_keyword(kw::Type) {
|
||||
// TYPE ITEM
|
||||
let (ident, ty, generics) = self.parse_type_alias()?;
|
||||
(ident, ItemKind::TyAlias(ty, generics))
|
||||
self.parse_type_alias()?
|
||||
} else if self.eat_keyword(kw::Enum) {
|
||||
// ENUM ITEM
|
||||
self.parse_item_enum()?
|
||||
@ -676,7 +675,10 @@ impl<'a> Parser<'a> {
|
||||
vis: &Visibility,
|
||||
) -> PResult<'a, (Ident, AssocItemKind)> {
|
||||
if self.eat_keyword(kw::Type) {
|
||||
self.parse_assoc_ty()
|
||||
match self.parse_type_alias()? {
|
||||
(ident, ItemKind::TyAlias(a, b, c)) => Ok((ident, AssocItemKind::TyAlias(a, b, c))),
|
||||
_ => unreachable!(),
|
||||
}
|
||||
} else if self.check_fn_front_matter() {
|
||||
let (ident, sig, generics, body) = self.parse_fn(at_end, attrs, req_name)?;
|
||||
Ok((ident, AssocItemKind::Fn(sig, generics, body)))
|
||||
@ -700,10 +702,12 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parses the following grammar:
|
||||
///
|
||||
/// AssocTy = Ident ["<"...">"] [":" [GenericBounds]] ["where" ...] ["=" Ty]
|
||||
fn parse_assoc_ty(&mut self) -> PResult<'a, (Ident, AssocItemKind)> {
|
||||
/// Parses a `type` alias with the following grammar:
|
||||
/// ```
|
||||
/// TypeAlias = "type" Ident Generics {":" GenericBounds}? {"=" Ty}? ";" ;
|
||||
/// ```
|
||||
/// The `"type"` has already been eaten.
|
||||
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, ItemKind)> {
|
||||
let ident = self.parse_ident()?;
|
||||
let mut generics = self.parse_generics()?;
|
||||
|
||||
@ -715,7 +719,7 @@ impl<'a> Parser<'a> {
|
||||
let default = if self.eat(&token::Eq) { Some(self.parse_ty()?) } else { None };
|
||||
self.expect_semi()?;
|
||||
|
||||
Ok((ident, AssocItemKind::TyAlias(generics, bounds, default)))
|
||||
Ok((ident, ItemKind::TyAlias(generics, bounds, default)))
|
||||
}
|
||||
|
||||
/// Parses a `UseTree`.
|
||||
@ -989,18 +993,6 @@ impl<'a> Parser<'a> {
|
||||
P(Ty { kind: TyKind::Infer, span: id.span, id: ast::DUMMY_NODE_ID })
|
||||
}
|
||||
|
||||
/// Parses the grammar:
|
||||
/// Ident ["<"...">"] ["where" ...] ("=" | ":") Ty ";"
|
||||
fn parse_type_alias(&mut self) -> PResult<'a, (Ident, P<Ty>, Generics)> {
|
||||
let ident = self.parse_ident()?;
|
||||
let mut tps = self.parse_generics()?;
|
||||
tps.where_clause = self.parse_where_clause()?;
|
||||
self.expect(&token::Eq)?;
|
||||
let ty = self.parse_ty()?;
|
||||
self.expect_semi()?;
|
||||
Ok((ident, ty, tps))
|
||||
}
|
||||
|
||||
/// Parses an enum declaration.
|
||||
fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
|
||||
let id = self.parse_ident()?;
|
||||
|
@ -601,141 +601,76 @@ impl<'a> Parser<'a> {
|
||||
)
|
||||
}
|
||||
|
||||
/// Expects and consumes a `+`. if `+=` is seen, replaces it with a `=`
|
||||
/// and continues. If a `+` is not seen, returns `false`.
|
||||
///
|
||||
/// This is used when token-splitting `+=` into `+`.
|
||||
/// See issue #47856 for an example of when this may occur.
|
||||
/// Eats the expected token if it's present possibly breaking
|
||||
/// compound tokens like multi-character operators in process.
|
||||
/// Returns `true` if the token was eaten.
|
||||
fn break_and_eat(&mut self, expected: TokenKind) -> bool {
|
||||
if self.token.kind == expected {
|
||||
self.bump();
|
||||
return true;
|
||||
}
|
||||
match self.token.kind.break_two_token_op() {
|
||||
Some((first, second)) if first == expected => {
|
||||
let first_span = self.sess.source_map().start_point(self.token.span);
|
||||
let second_span = self.token.span.with_lo(first_span.hi());
|
||||
self.set_token(Token::new(first, first_span));
|
||||
self.bump_with(Token::new(second, second_span));
|
||||
true
|
||||
}
|
||||
_ => {
|
||||
self.expected_tokens.push(TokenType::Token(expected));
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Eats `+` possibly breaking tokens like `+=` in process.
|
||||
fn eat_plus(&mut self) -> bool {
|
||||
self.expected_tokens.push(TokenType::Token(token::BinOp(token::Plus)));
|
||||
match self.token.kind {
|
||||
token::BinOp(token::Plus) => {
|
||||
self.bump();
|
||||
true
|
||||
}
|
||||
token::BinOpEq(token::Plus) => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
self.bump_with(token::Eq, self.token.span.with_lo(start_point.hi()));
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
self.break_and_eat(token::BinOp(token::Plus))
|
||||
}
|
||||
|
||||
/// Expects and consumes an `&`. If `&&` is seen, replaces it with a single
|
||||
/// `&` and continues. If an `&` is not seen, signals an error.
|
||||
/// Eats `&` possibly breaking tokens like `&&` in process.
|
||||
/// Signals an error if `&` is not eaten.
|
||||
fn expect_and(&mut self) -> PResult<'a, ()> {
|
||||
self.expected_tokens.push(TokenType::Token(token::BinOp(token::And)));
|
||||
match self.token.kind {
|
||||
token::BinOp(token::And) => {
|
||||
self.bump();
|
||||
Ok(())
|
||||
}
|
||||
token::AndAnd => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
Ok(self
|
||||
.bump_with(token::BinOp(token::And), self.token.span.with_lo(start_point.hi())))
|
||||
}
|
||||
_ => self.unexpected(),
|
||||
}
|
||||
if self.break_and_eat(token::BinOp(token::And)) { Ok(()) } else { self.unexpected() }
|
||||
}
|
||||
|
||||
/// Expects and consumes an `|`. If `||` is seen, replaces it with a single
|
||||
/// `|` and continues. If an `|` is not seen, signals an error.
|
||||
/// Eats `|` possibly breaking tokens like `||` in process.
|
||||
/// Signals an error if `|` was not eaten.
|
||||
fn expect_or(&mut self) -> PResult<'a, ()> {
|
||||
self.expected_tokens.push(TokenType::Token(token::BinOp(token::Or)));
|
||||
match self.token.kind {
|
||||
token::BinOp(token::Or) => {
|
||||
self.bump();
|
||||
Ok(())
|
||||
}
|
||||
token::OrOr => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
Ok(self
|
||||
.bump_with(token::BinOp(token::Or), self.token.span.with_lo(start_point.hi())))
|
||||
}
|
||||
_ => self.unexpected(),
|
||||
}
|
||||
if self.break_and_eat(token::BinOp(token::Or)) { Ok(()) } else { self.unexpected() }
|
||||
}
|
||||
|
||||
/// Attempts to consume a `<`. If `<<` is seen, replaces it with a single
|
||||
/// `<` and continue. If `<-` is seen, replaces it with a single `<`
|
||||
/// and continue. If a `<` is not seen, returns false.
|
||||
///
|
||||
/// This is meant to be used when parsing generics on a path to get the
|
||||
/// starting token.
|
||||
/// Eats `<` possibly breaking tokens like `<<` in process.
|
||||
fn eat_lt(&mut self) -> bool {
|
||||
self.expected_tokens.push(TokenType::Token(token::Lt));
|
||||
let ate = match self.token.kind {
|
||||
token::Lt => {
|
||||
self.bump();
|
||||
true
|
||||
}
|
||||
token::BinOp(token::Shl) => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
self.bump_with(token::Lt, self.token.span.with_lo(start_point.hi()));
|
||||
true
|
||||
}
|
||||
token::LArrow => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
self.bump_with(
|
||||
token::BinOp(token::Minus),
|
||||
self.token.span.with_lo(start_point.hi()),
|
||||
);
|
||||
true
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
let ate = self.break_and_eat(token::Lt);
|
||||
if ate {
|
||||
// See doc comment for `unmatched_angle_bracket_count`.
|
||||
self.unmatched_angle_bracket_count += 1;
|
||||
self.max_angle_bracket_count += 1;
|
||||
debug!("eat_lt: (increment) count={:?}", self.unmatched_angle_bracket_count);
|
||||
}
|
||||
|
||||
ate
|
||||
}
|
||||
|
||||
/// Eats `<` possibly breaking tokens like `<<` in process.
|
||||
/// Signals an error if `<` was not eaten.
|
||||
fn expect_lt(&mut self) -> PResult<'a, ()> {
|
||||
if !self.eat_lt() { self.unexpected() } else { Ok(()) }
|
||||
if self.eat_lt() { Ok(()) } else { self.unexpected() }
|
||||
}
|
||||
|
||||
/// Expects and consumes a single `>` token. if a `>>` is seen, replaces it
|
||||
/// with a single `>` and continues. If a `>` is not seen, signals an error.
|
||||
/// Eats `>` possibly breaking tokens like `>>` in process.
|
||||
/// Signals an error if `>` was not eaten.
|
||||
fn expect_gt(&mut self) -> PResult<'a, ()> {
|
||||
self.expected_tokens.push(TokenType::Token(token::Gt));
|
||||
let ate = match self.token.kind {
|
||||
token::Gt => {
|
||||
self.bump();
|
||||
Some(())
|
||||
if self.break_and_eat(token::Gt) {
|
||||
// See doc comment for `unmatched_angle_bracket_count`.
|
||||
if self.unmatched_angle_bracket_count > 0 {
|
||||
self.unmatched_angle_bracket_count -= 1;
|
||||
debug!("expect_gt: (decrement) count={:?}", self.unmatched_angle_bracket_count);
|
||||
}
|
||||
token::BinOp(token::Shr) => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
Some(self.bump_with(token::Gt, self.token.span.with_lo(start_point.hi())))
|
||||
}
|
||||
token::BinOpEq(token::Shr) => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
Some(self.bump_with(token::Ge, self.token.span.with_lo(start_point.hi())))
|
||||
}
|
||||
token::Ge => {
|
||||
let start_point = self.sess.source_map().start_point(self.token.span);
|
||||
Some(self.bump_with(token::Eq, self.token.span.with_lo(start_point.hi())))
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
|
||||
match ate {
|
||||
Some(_) => {
|
||||
// See doc comment for `unmatched_angle_bracket_count`.
|
||||
if self.unmatched_angle_bracket_count > 0 {
|
||||
self.unmatched_angle_bracket_count -= 1;
|
||||
debug!("expect_gt: (decrement) count={:?}", self.unmatched_angle_bracket_count);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => self.unexpected(),
|
||||
Ok(())
|
||||
} else {
|
||||
self.unexpected()
|
||||
}
|
||||
}
|
||||
|
||||
@ -903,10 +838,10 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Advance the parser by one token.
|
||||
pub fn bump(&mut self) {
|
||||
/// Advance the parser by one token using provided token as the next one.
|
||||
fn bump_with(&mut self, next_token: Token) {
|
||||
// Bumping after EOF is a bad sign, usually an infinite loop.
|
||||
if self.prev_token.kind == TokenKind::Eof {
|
||||
// Bumping after EOF is a bad sign, usually an infinite loop.
|
||||
let msg = "attempted to bump the parser past EOF (may be stuck in a loop)";
|
||||
self.span_bug(self.token.span, msg);
|
||||
}
|
||||
@ -914,30 +849,19 @@ impl<'a> Parser<'a> {
|
||||
// Update the current and previous tokens.
|
||||
self.prev_token = self.token.take();
|
||||
self.unnormalized_prev_token = self.unnormalized_token.take();
|
||||
let next_token = self.next_tok(self.unnormalized_prev_token.span);
|
||||
self.set_token(next_token);
|
||||
|
||||
// Update fields derived from the previous token.
|
||||
self.prev_span = self.unnormalized_prev_token.span;
|
||||
|
||||
// Diagnostics.
|
||||
self.expected_tokens.clear();
|
||||
}
|
||||
|
||||
/// Advances the parser using provided token as a next one. Use this when
|
||||
/// consuming a part of a token. For example a single `<` from `<<`.
|
||||
/// FIXME: this function sets the previous token data to some semi-nonsensical values
|
||||
/// which kind of work because they are currently used in very limited ways in practice.
|
||||
/// Correct token kinds and spans need to be calculated instead.
|
||||
fn bump_with(&mut self, next: TokenKind, span: Span) {
|
||||
// Update the current and previous tokens.
|
||||
self.prev_token = self.token.take();
|
||||
self.unnormalized_prev_token = self.unnormalized_token.take();
|
||||
self.set_token(Token::new(next, span));
|
||||
|
||||
// Update fields derived from the previous token.
|
||||
self.prev_span = self.unnormalized_prev_token.span.with_hi(span.lo());
|
||||
|
||||
self.expected_tokens.clear();
|
||||
/// Advance the parser by one token.
|
||||
pub fn bump(&mut self) {
|
||||
let next_token = self.next_tok(self.unnormalized_token.span);
|
||||
self.bump_with(next_token);
|
||||
}
|
||||
|
||||
/// Look-ahead `dist` tokens of `self.token` and get access to that token there.
|
||||
|
@ -144,11 +144,11 @@ enum LiveNodeKind {
|
||||
}
|
||||
|
||||
fn live_node_kind_to_string(lnk: LiveNodeKind, tcx: TyCtxt<'_>) -> String {
|
||||
let cm = tcx.sess.source_map();
|
||||
let sm = tcx.sess.source_map();
|
||||
match lnk {
|
||||
UpvarNode(s) => format!("Upvar node [{}]", cm.span_to_string(s)),
|
||||
ExprNode(s) => format!("Expr node [{}]", cm.span_to_string(s)),
|
||||
VarDefNode(s) => format!("Var def node [{}]", cm.span_to_string(s)),
|
||||
UpvarNode(s) => format!("Upvar node [{}]", sm.span_to_string(s)),
|
||||
ExprNode(s) => format!("Expr node [{}]", sm.span_to_string(s)),
|
||||
VarDefNode(s) => format!("Var def node [{}]", sm.span_to_string(s)),
|
||||
ExitNode => "Exit node".to_owned(),
|
||||
}
|
||||
}
|
||||
|
@ -718,8 +718,8 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> {
|
||||
}
|
||||
|
||||
// These items live in the type namespace.
|
||||
ItemKind::TyAlias(ref ty, _) => {
|
||||
let def_kind = match ty.kind.opaque_top_hack() {
|
||||
ItemKind::TyAlias(_, _, ref ty) => {
|
||||
let def_kind = match ty.as_deref().and_then(|ty| ty.kind.opaque_top_hack()) {
|
||||
None => DefKind::TyAlias,
|
||||
Some(_) => DefKind::OpaqueTy,
|
||||
};
|
||||
|
@ -90,9 +90,9 @@ impl<'tcx> Into<MissingLifetimeSpot<'tcx>> for &'tcx hir::Generics<'tcx> {
|
||||
/// *Attention*: the method used is very fragile since it essentially duplicates the work of the
|
||||
/// parser. If you need to use this function or something similar, please consider updating the
|
||||
/// `source_map` functions and this function to something more robust.
|
||||
fn reduce_impl_span_to_impl_keyword(cm: &SourceMap, impl_span: Span) -> Span {
|
||||
let impl_span = cm.span_until_char(impl_span, '<');
|
||||
let impl_span = cm.span_until_whitespace(impl_span);
|
||||
fn reduce_impl_span_to_impl_keyword(sm: &SourceMap, impl_span: Span) -> Span {
|
||||
let impl_span = sm.span_until_char(impl_span, '<');
|
||||
let impl_span = sm.span_until_whitespace(impl_span);
|
||||
impl_span
|
||||
}
|
||||
|
||||
@ -136,14 +136,14 @@ impl<'a> Resolver<'a> {
|
||||
);
|
||||
err.span_label(span, format!("use of generic parameter from outer function"));
|
||||
|
||||
let cm = self.session.source_map();
|
||||
let sm = self.session.source_map();
|
||||
match outer_res {
|
||||
Res::SelfTy(maybe_trait_defid, maybe_impl_defid) => {
|
||||
if let Some(impl_span) =
|
||||
maybe_impl_defid.and_then(|def_id| self.definitions.opt_span(def_id))
|
||||
{
|
||||
err.span_label(
|
||||
reduce_impl_span_to_impl_keyword(cm, impl_span),
|
||||
reduce_impl_span_to_impl_keyword(sm, impl_span),
|
||||
"`Self` type implicitly declared here, by this `impl`",
|
||||
);
|
||||
}
|
||||
@ -180,7 +180,7 @@ impl<'a> Resolver<'a> {
|
||||
// Try to retrieve the span of the function signature and generate a new
|
||||
// message with a local type or const parameter.
|
||||
let sugg_msg = &format!("try using a local generic parameter instead");
|
||||
if let Some((sugg_span, snippet)) = cm.generate_local_type_param_snippet(span) {
|
||||
if let Some((sugg_span, snippet)) = sm.generate_local_type_param_snippet(span) {
|
||||
// Suggest the modification to the user
|
||||
err.span_suggestion(
|
||||
sugg_span,
|
||||
@ -188,7 +188,7 @@ impl<'a> Resolver<'a> {
|
||||
snippet,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
} else if let Some(sp) = cm.generate_fn_name_span(span) {
|
||||
} else if let Some(sp) = sm.generate_fn_name_span(span) {
|
||||
err.span_label(
|
||||
sp,
|
||||
format!("try adding a local generic parameter in this method instead"),
|
||||
|
@ -797,7 +797,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
|
||||
debug!("(resolving item) resolving {} ({:?})", name, item.kind);
|
||||
|
||||
match item.kind {
|
||||
ItemKind::TyAlias(_, ref generics) | ItemKind::Fn(_, ref generics, _) => {
|
||||
ItemKind::TyAlias(ref generics, _, _) | ItemKind::Fn(_, ref generics, _) => {
|
||||
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), |this| {
|
||||
visit::walk_item(this, item)
|
||||
});
|
||||
|
@ -725,21 +725,21 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
|
||||
/// Only used in a specific case of type ascription suggestions
|
||||
fn get_colon_suggestion_span(&self, start: Span) -> Span {
|
||||
let cm = self.r.session.source_map();
|
||||
start.to(cm.next_point(start))
|
||||
let sm = self.r.session.source_map();
|
||||
start.to(sm.next_point(start))
|
||||
}
|
||||
|
||||
fn type_ascription_suggestion(&self, err: &mut DiagnosticBuilder<'_>, base_span: Span) {
|
||||
let cm = self.r.session.source_map();
|
||||
let base_snippet = cm.span_to_snippet(base_span);
|
||||
let sm = self.r.session.source_map();
|
||||
let base_snippet = sm.span_to_snippet(base_span);
|
||||
if let Some(sp) = self.diagnostic_metadata.current_type_ascription.last() {
|
||||
let mut sp = *sp;
|
||||
loop {
|
||||
// Try to find the `:`; bail on first non-':' / non-whitespace.
|
||||
sp = cm.next_point(sp);
|
||||
if let Ok(snippet) = cm.span_to_snippet(sp.to(cm.next_point(sp))) {
|
||||
let line_sp = cm.lookup_char_pos(sp.hi()).line;
|
||||
let line_base_sp = cm.lookup_char_pos(base_span.lo()).line;
|
||||
sp = sm.next_point(sp);
|
||||
if let Ok(snippet) = sm.span_to_snippet(sp.to(sm.next_point(sp))) {
|
||||
let line_sp = sm.lookup_char_pos(sp.hi()).line;
|
||||
let line_base_sp = sm.lookup_char_pos(base_span.lo()).line;
|
||||
if snippet == ":" {
|
||||
let mut show_label = true;
|
||||
if line_sp != line_base_sp {
|
||||
@ -753,7 +753,7 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
let colon_sp = self.get_colon_suggestion_span(sp);
|
||||
let after_colon_sp =
|
||||
self.get_colon_suggestion_span(colon_sp.shrink_to_hi());
|
||||
if !cm
|
||||
if !sm
|
||||
.span_to_snippet(after_colon_sp)
|
||||
.map(|s| s == " ")
|
||||
.unwrap_or(false)
|
||||
@ -770,8 +770,8 @@ impl<'a> LateResolutionVisitor<'a, '_, '_> {
|
||||
let mut sp = after_colon_sp;
|
||||
for _ in 0..100 {
|
||||
// Try to find an assignment
|
||||
sp = cm.next_point(sp);
|
||||
let snippet = cm.span_to_snippet(sp.to(cm.next_point(sp)));
|
||||
sp = sm.next_point(sp);
|
||||
let snippet = sm.span_to_snippet(sp.to(sm.next_point(sp)));
|
||||
match snippet {
|
||||
Ok(ref x) if x.as_str() == "=" => {
|
||||
err.span_suggestion(
|
||||
|
@ -1233,8 +1233,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
|
||||
let qualname =
|
||||
format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id)));
|
||||
|
||||
let cm = self.tcx.sess.source_map();
|
||||
let filename = cm.span_to_filename(span);
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let filename = sm.span_to_filename(span);
|
||||
let data_id = id_from_node_id(id, &self.save_ctxt);
|
||||
let children = m.items.iter().map(|i| id_from_node_id(i.id, &self.save_ctxt)).collect();
|
||||
let span = self.span_from_span(span);
|
||||
@ -1311,12 +1311,15 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
|
||||
self.process_mod(item);
|
||||
visit::walk_mod(self, m);
|
||||
}
|
||||
TyAlias(ref ty, ref ty_params) => {
|
||||
TyAlias(ref ty_params, _, ref ty) => {
|
||||
let qualname = format!(
|
||||
"::{}",
|
||||
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
|
||||
);
|
||||
let value = ty_to_string(&ty);
|
||||
let value = match ty {
|
||||
Some(ty) => ty_to_string(&ty),
|
||||
None => "_".to_string(),
|
||||
};
|
||||
if !self.span.filter_generated(item.ident.span) {
|
||||
let span = self.span_from_span(item.ident.span);
|
||||
let id = id_from_node_id(item.id, &self.save_ctxt);
|
||||
@ -1341,7 +1344,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
|
||||
);
|
||||
}
|
||||
|
||||
self.visit_ty(&ty);
|
||||
walk_list!(self, visit_ty, ty);
|
||||
self.process_generic_params(ty_params, &qualname, item.id);
|
||||
}
|
||||
Mac(_) => (),
|
||||
|
@ -66,9 +66,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
|
||||
fn span_from_span(&self, span: Span) -> SpanData {
|
||||
use rls_span::{Column, Row};
|
||||
|
||||
let cm = self.tcx.sess.source_map();
|
||||
let start = cm.lookup_char_pos(span.lo());
|
||||
let end = cm.lookup_char_pos(span.hi());
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let start = sm.lookup_char_pos(span.lo());
|
||||
let end = sm.lookup_char_pos(span.hi());
|
||||
|
||||
SpanData {
|
||||
file_name: start.file.name.to_string().into(),
|
||||
@ -258,8 +258,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
|
||||
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
|
||||
);
|
||||
|
||||
let cm = self.tcx.sess.source_map();
|
||||
let filename = cm.span_to_filename(m.inner);
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let filename = sm.span_to_filename(m.inner);
|
||||
|
||||
filter!(self.span_utils, item.ident.span);
|
||||
|
||||
|
@ -423,12 +423,15 @@ impl Sig for ast::Item {
|
||||
|
||||
Ok(Signature { text, defs, refs: vec![] })
|
||||
}
|
||||
ast::ItemKind::TyAlias(ref ty, ref generics) => {
|
||||
ast::ItemKind::TyAlias(ref generics, _, ref ty) => {
|
||||
let text = "type ".to_owned();
|
||||
let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?;
|
||||
|
||||
sig.text.push_str(" = ");
|
||||
let ty = ty.make(offset + sig.text.len(), id, scx)?;
|
||||
let ty = match ty {
|
||||
Some(ty) => ty.make(offset + sig.text.len(), id, scx)?,
|
||||
None => Err("Ty")?,
|
||||
};
|
||||
sig.text.push_str(&ty.text);
|
||||
sig.text.push(';');
|
||||
|
||||
|
@ -124,9 +124,9 @@ pub struct ParseSess {
|
||||
|
||||
impl ParseSess {
|
||||
pub fn new(file_path_mapping: FilePathMapping) -> Self {
|
||||
let cm = Lrc::new(SourceMap::new(file_path_mapping));
|
||||
let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, None, Some(cm.clone()));
|
||||
ParseSess::with_span_handler(handler, cm)
|
||||
let sm = Lrc::new(SourceMap::new(file_path_mapping));
|
||||
let handler = Handler::with_tty_emitter(ColorConfig::Auto, true, None, Some(sm.clone()));
|
||||
ParseSess::with_span_handler(handler, sm)
|
||||
}
|
||||
|
||||
pub fn with_span_handler(handler: Handler, source_map: Lrc<SourceMap>) -> Self {
|
||||
@ -148,9 +148,9 @@ impl ParseSess {
|
||||
}
|
||||
|
||||
pub fn with_silent_emitter() -> Self {
|
||||
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let handler = Handler::with_emitter(false, None, Box::new(SilentEmitter));
|
||||
ParseSess::with_span_handler(handler, cm)
|
||||
ParseSess::with_span_handler(handler, sm)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -13,14 +13,14 @@ struct CacheEntry {
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CachingSourceMapView<'cm> {
|
||||
source_map: &'cm SourceMap,
|
||||
pub struct CachingSourceMapView<'sm> {
|
||||
source_map: &'sm SourceMap,
|
||||
line_cache: [CacheEntry; 3],
|
||||
time_stamp: usize,
|
||||
}
|
||||
|
||||
impl<'cm> CachingSourceMapView<'cm> {
|
||||
pub fn new(source_map: &'cm SourceMap) -> CachingSourceMapView<'cm> {
|
||||
impl<'sm> CachingSourceMapView<'sm> {
|
||||
pub fn new(source_map: &'sm SourceMap) -> CachingSourceMapView<'sm> {
|
||||
let files = source_map.files();
|
||||
let first_file = files[0].clone();
|
||||
let entry = CacheEntry {
|
||||
|
@ -324,13 +324,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
hir_id: hir::HirId,
|
||||
sp: Span,
|
||||
) -> bool {
|
||||
let cm = self.sess().source_map();
|
||||
let sm = self.sess().source_map();
|
||||
let parent_id = self.tcx.hir().get_parent_node(hir_id);
|
||||
if let Some(parent) = self.tcx.hir().find(parent_id) {
|
||||
// Account for fields
|
||||
if let Node::Expr(hir::Expr { kind: hir::ExprKind::Struct(_, fields, ..), .. }) = parent
|
||||
{
|
||||
if let Ok(src) = cm.span_to_snippet(sp) {
|
||||
if let Ok(src) = sm.span_to_snippet(sp) {
|
||||
for field in *fields {
|
||||
if field.ident.as_str() == src && field.is_shorthand {
|
||||
return true;
|
||||
@ -364,9 +364,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
checked_ty: Ty<'tcx>,
|
||||
expected: Ty<'tcx>,
|
||||
) -> Option<(Span, &'static str, String)> {
|
||||
let cm = self.sess().source_map();
|
||||
let sm = self.sess().source_map();
|
||||
let sp = expr.span;
|
||||
if !cm.span_to_filename(sp).is_real() {
|
||||
if !sm.span_to_filename(sp).is_real() {
|
||||
// Ignore if span is from within a macro #41858, #58298. We previously used the macro
|
||||
// call span, but that breaks down when the type error comes from multiple calls down.
|
||||
return None;
|
||||
@ -388,7 +388,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if arr == self.tcx.types.u8 =>
|
||||
{
|
||||
if let hir::ExprKind::Lit(_) = expr.kind {
|
||||
if let Ok(src) = cm.span_to_snippet(sp) {
|
||||
if let Ok(src) = sm.span_to_snippet(sp) {
|
||||
if src.starts_with("b\"") {
|
||||
return Some((
|
||||
sp,
|
||||
@ -403,7 +403,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if arr == self.tcx.types.u8 =>
|
||||
{
|
||||
if let hir::ExprKind::Lit(_) = expr.kind {
|
||||
if let Ok(src) = cm.span_to_snippet(sp) {
|
||||
if let Ok(src) = sm.span_to_snippet(sp) {
|
||||
if src.starts_with("\"") {
|
||||
return Some((
|
||||
sp,
|
||||
@ -450,7 +450,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
sugg_sp = arg.span;
|
||||
}
|
||||
}
|
||||
if let Ok(src) = cm.span_to_snippet(sugg_sp) {
|
||||
if let Ok(src) = sm.span_to_snippet(sugg_sp) {
|
||||
let needs_parens = match expr.kind {
|
||||
// parenthesize if needed (Issue #46756)
|
||||
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
|
||||
@ -480,7 +480,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// | |
|
||||
// consider dereferencing here: `*opt` |
|
||||
// expected mutable reference, found enum `Option`
|
||||
if let Ok(src) = cm.span_to_snippet(left_expr.span) {
|
||||
if let Ok(src) = sm.span_to_snippet(left_expr.span) {
|
||||
return Some((
|
||||
left_expr.span,
|
||||
"consider dereferencing here to assign to the mutable \
|
||||
@ -516,8 +516,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
{
|
||||
// We have `&T`, check if what was expected was `T`. If so,
|
||||
// we may want to suggest removing a `&`.
|
||||
if !cm.span_to_filename(expr.span).is_real() {
|
||||
if let Ok(code) = cm.span_to_snippet(sp) {
|
||||
if !sm.span_to_filename(expr.span).is_real() {
|
||||
if let Ok(code) = sm.span_to_snippet(sp) {
|
||||
if code.chars().next() == Some('&') {
|
||||
return Some((
|
||||
sp,
|
||||
@ -528,7 +528,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
}
|
||||
return None;
|
||||
}
|
||||
if let Ok(code) = cm.span_to_snippet(expr.span) {
|
||||
if let Ok(code) = sm.span_to_snippet(expr.span) {
|
||||
return Some((sp, "consider removing the borrow", code));
|
||||
}
|
||||
}
|
||||
@ -562,7 +562,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
let is_copy = self.infcx.type_is_copy_modulo_regions(self.param_env, expected, sp);
|
||||
|
||||
if is_copy && impls_deref {
|
||||
if let Ok(code) = cm.span_to_snippet(sp) {
|
||||
if let Ok(code) = sm.span_to_snippet(sp) {
|
||||
let message = if checked_ty.is_region_ptr() {
|
||||
"consider dereferencing the borrow"
|
||||
} else {
|
||||
|
@ -33,8 +33,8 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> {
|
||||
);
|
||||
let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
|
||||
let trait_def_id = trait_ref.def_id;
|
||||
let cm = self.tcx.sess.source_map();
|
||||
let sp = cm.def_span(item.span);
|
||||
let sm = self.tcx.sess.source_map();
|
||||
let sp = sm.def_span(item.span);
|
||||
match traits::orphan_check(self.tcx, def_id) {
|
||||
Ok(()) => {}
|
||||
Err(traits::OrphanCheckErr::NonLocalInputType(tys)) => {
|
||||
|
@ -263,9 +263,9 @@ impl Clean<Item> for doctree::Module<'_> {
|
||||
// determine if we should display the inner contents or
|
||||
// the outer `mod` item for the source code.
|
||||
let whence = {
|
||||
let cm = cx.sess().source_map();
|
||||
let outer = cm.lookup_char_pos(self.where_outer.lo());
|
||||
let inner = cm.lookup_char_pos(self.where_inner.lo());
|
||||
let sm = cx.sess().source_map();
|
||||
let outer = sm.lookup_char_pos(self.where_outer.lo());
|
||||
let inner = sm.lookup_char_pos(self.where_inner.lo());
|
||||
if outer.file.start_pos == inner.file.start_pos {
|
||||
// mod foo { ... }
|
||||
self.where_outer
|
||||
@ -1917,10 +1917,10 @@ impl Clean<Span> for rustc_span::Span {
|
||||
return Span::empty();
|
||||
}
|
||||
|
||||
let cm = cx.sess().source_map();
|
||||
let filename = cm.span_to_filename(*self);
|
||||
let lo = cm.lookup_char_pos(self.lo());
|
||||
let hi = cm.lookup_char_pos(self.hi());
|
||||
let sm = cx.sess().source_map();
|
||||
let filename = sm.span_to_filename(*self);
|
||||
let lo = sm.lookup_char_pos(self.lo());
|
||||
let hi = sm.lookup_char_pos(self.hi());
|
||||
Span {
|
||||
filename,
|
||||
loline: lo.line,
|
||||
|
@ -177,7 +177,7 @@ pub fn new_handler(
|
||||
Box::new(
|
||||
EmitterWriter::stderr(
|
||||
color_config,
|
||||
source_map.map(|cm| cm as _),
|
||||
source_map.map(|sm| sm as _),
|
||||
short,
|
||||
debugging_opts.teach,
|
||||
debugging_opts.terminal_width,
|
||||
|
@ -38,11 +38,11 @@ pub fn render_with_highlighting(
|
||||
}
|
||||
|
||||
let sess = ParseSess::with_silent_emitter();
|
||||
let fm = sess
|
||||
let sf = sess
|
||||
.source_map()
|
||||
.new_source_file(FileName::Custom(String::from("rustdoc-highlighting")), src.to_owned());
|
||||
let highlight_result = rustc_driver::catch_fatal_errors(|| {
|
||||
let lexer = lexer::StringReader::new(&sess, fm, None);
|
||||
let lexer = lexer::StringReader::new(&sess, sf, None);
|
||||
let mut classifier = Classifier::new(lexer, sess.source_map());
|
||||
|
||||
let mut highlighted_source = vec![];
|
||||
|
@ -32,9 +32,9 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
|
||||
|
||||
let emitter = BufferEmitter { messages: Lrc::clone(&buffered_messages) };
|
||||
|
||||
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let handler = Handler::with_emitter(false, None, Box::new(emitter));
|
||||
let sess = ParseSess::with_span_handler(handler, cm);
|
||||
let sess = ParseSess::with_span_handler(handler, sm);
|
||||
let source_file = sess.source_map().new_source_file(
|
||||
FileName::Custom(String::from("doctest")),
|
||||
dox[code_block.code].to_owned(),
|
||||
|
@ -402,12 +402,12 @@ pub fn make_test(
|
||||
|
||||
// Any errors in parsing should also appear when the doctest is compiled for real, so just
|
||||
// send all the errors that libsyntax emits directly into a `Sink` instead of stderr.
|
||||
let cm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let emitter =
|
||||
EmitterWriter::new(box io::sink(), None, false, false, false, None, false);
|
||||
// FIXME(misdreavus): pass `-Z treat-err-as-bug` to the doctest parser
|
||||
let handler = Handler::with_emitter(false, None, box emitter);
|
||||
let sess = ParseSess::with_span_handler(handler, cm);
|
||||
let sess = ParseSess::with_span_handler(handler, sm);
|
||||
|
||||
let mut found_main = false;
|
||||
let mut found_extern_crate = cratename.is_none();
|
||||
|
@ -2524,7 +2524,7 @@ pub enum ItemKind {
|
||||
/// A type alias (`type`).
|
||||
///
|
||||
/// E.g., `type Foo = Bar<u8>;`.
|
||||
TyAlias(P<Ty>, Generics),
|
||||
TyAlias(Generics, GenericBounds, Option<P<Ty>>),
|
||||
/// An enum definition (`enum`).
|
||||
///
|
||||
/// E.g., `enum Foo<A, B> { C<A>, D<B> }`.
|
||||
@ -2594,7 +2594,7 @@ impl ItemKind {
|
||||
pub fn generics(&self) -> Option<&Generics> {
|
||||
match self {
|
||||
Self::Fn(_, generics, _)
|
||||
| Self::TyAlias(_, generics)
|
||||
| Self::TyAlias(generics, ..)
|
||||
| Self::Enum(_, generics)
|
||||
| Self::Struct(_, generics)
|
||||
| Self::Union(_, generics)
|
||||
|
@ -902,9 +902,10 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
|
||||
ItemKind::Mod(m) => vis.visit_mod(m),
|
||||
ItemKind::ForeignMod(nm) => vis.visit_foreign_mod(nm),
|
||||
ItemKind::GlobalAsm(_ga) => {}
|
||||
ItemKind::TyAlias(ty, generics) => {
|
||||
vis.visit_ty(ty);
|
||||
ItemKind::TyAlias(generics, bounds, ty) => {
|
||||
vis.visit_generics(generics);
|
||||
visit_bounds(bounds, vis);
|
||||
visit_opt(ty, |ty| vis.visit_ty(ty));
|
||||
}
|
||||
ItemKind::Enum(EnumDef { variants }, generics) => {
|
||||
variants.flat_map_in_place(|variant| vis.flat_map_variant(variant));
|
||||
|
@ -270,6 +270,39 @@ impl TokenKind {
|
||||
Literal(Lit::new(kind, symbol, suffix))
|
||||
}
|
||||
|
||||
// An approximation to proc-macro-style single-character operators used by rustc parser.
|
||||
// If the operator token can be broken into two tokens, the first of which is single-character,
|
||||
// then this function performs that operation, otherwise it returns `None`.
|
||||
pub fn break_two_token_op(&self) -> Option<(TokenKind, TokenKind)> {
|
||||
Some(match *self {
|
||||
Le => (Lt, Eq),
|
||||
EqEq => (Eq, Eq),
|
||||
Ne => (Not, Eq),
|
||||
Ge => (Gt, Eq),
|
||||
AndAnd => (BinOp(And), BinOp(And)),
|
||||
OrOr => (BinOp(Or), BinOp(Or)),
|
||||
BinOp(Shl) => (Lt, Lt),
|
||||
BinOp(Shr) => (Gt, Gt),
|
||||
BinOpEq(Plus) => (BinOp(Plus), Eq),
|
||||
BinOpEq(Minus) => (BinOp(Minus), Eq),
|
||||
BinOpEq(Star) => (BinOp(Star), Eq),
|
||||
BinOpEq(Slash) => (BinOp(Slash), Eq),
|
||||
BinOpEq(Percent) => (BinOp(Percent), Eq),
|
||||
BinOpEq(Caret) => (BinOp(Caret), Eq),
|
||||
BinOpEq(And) => (BinOp(And), Eq),
|
||||
BinOpEq(Or) => (BinOp(Or), Eq),
|
||||
BinOpEq(Shl) => (Lt, Le),
|
||||
BinOpEq(Shr) => (Gt, Ge),
|
||||
DotDot => (Dot, Dot),
|
||||
DotDotDot => (Dot, DotDot),
|
||||
ModSep => (Colon, Colon),
|
||||
RArrow => (BinOp(Minus), Gt),
|
||||
LArrow => (Lt, BinOp(Minus)),
|
||||
FatArrow => (Eq, Gt),
|
||||
_ => return None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns tokens that are likely to be typed accidentally instead of the current token.
|
||||
/// Enables better error recovery when the wrong token is found.
|
||||
pub fn similar_tokens(&self) -> Option<Vec<TokenKind>> {
|
||||
|
@ -189,8 +189,8 @@ fn split_block_comment_into_lines(text: &str, col: CharPos) -> Vec<String> {
|
||||
// it appears this function is called only from pprust... that's
|
||||
// probably not a good thing.
|
||||
pub fn gather_comments(sm: &SourceMap, path: FileName, src: String) -> Vec<Comment> {
|
||||
let cm = SourceMap::new(sm.path_mapping().clone());
|
||||
let source_file = cm.new_source_file(path, src);
|
||||
let sm = SourceMap::new(sm.path_mapping().clone());
|
||||
let source_file = sm.new_source_file(path, src);
|
||||
let text = (*source_file.src.as_ref().unwrap()).clone();
|
||||
|
||||
let text: &str = text.as_str();
|
||||
|
@ -312,9 +312,10 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
|
||||
walk_list!(visitor, visit_foreign_item, &foreign_module.items);
|
||||
}
|
||||
ItemKind::GlobalAsm(ref ga) => visitor.visit_global_asm(ga),
|
||||
ItemKind::TyAlias(ref typ, ref generics) => {
|
||||
visitor.visit_ty(typ);
|
||||
visitor.visit_generics(generics)
|
||||
ItemKind::TyAlias(ref generics, ref bounds, ref ty) => {
|
||||
visitor.visit_generics(generics);
|
||||
walk_list!(visitor, visit_param_bound, bounds);
|
||||
walk_list!(visitor, visit_ty, ty);
|
||||
}
|
||||
ItemKind::Enum(ref enum_definition, ref generics) => {
|
||||
visitor.visit_generics(generics);
|
||||
|
@ -5,6 +5,6 @@ type A where 'a:, = u8; // OK
|
||||
type A where 'a: 'b + 'c = u8; // OK
|
||||
type A where = u8; // OK
|
||||
type A where 'a: 'b + = u8; // OK
|
||||
type A where , = u8; //~ ERROR expected one of `=`, lifetime, or type, found `,`
|
||||
type A where , = u8; //~ ERROR expected one of `;`, `=`, lifetime, or type, found `,`
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,8 +1,8 @@
|
||||
error: expected one of `=`, lifetime, or type, found `,`
|
||||
error: expected one of `;`, `=`, lifetime, or type, found `,`
|
||||
--> $DIR/bounds-lifetime-where.rs:8:14
|
||||
|
|
||||
LL | type A where , = u8;
|
||||
| ^ expected one of `=`, lifetime, or type
|
||||
| ^ expected one of `;`, `=`, lifetime, or type
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
20
src/test/ui/parser/item-free-type-bounds-semantic-fail.rs
Normal file
20
src/test/ui/parser/item-free-type-bounds-semantic-fail.rs
Normal file
@ -0,0 +1,20 @@
|
||||
fn main() {}
|
||||
|
||||
fn semantics() {
|
||||
type A: Ord;
|
||||
//~^ ERROR bounds on `type`s in this context have no effect
|
||||
//~| ERROR free type alias without body
|
||||
type B: Ord = u8;
|
||||
//~^ ERROR bounds on `type`s in this context have no effect
|
||||
type C: Ord where 'static: 'static = u8;
|
||||
//~^ ERROR bounds on `type`s in this context have no effect
|
||||
type D<_T>: Ord;
|
||||
//~^ ERROR bounds on `type`s in this context have no effect
|
||||
//~| ERROR free type alias without body
|
||||
type E<_T>: Ord = u8;
|
||||
//~^ ERROR bounds on `type`s in this context have no effect
|
||||
//~| ERROR type parameter `_T` is unused
|
||||
type F<_T>: Ord where 'static: 'static = u8;
|
||||
//~^ ERROR bounds on `type`s in this context have no effect
|
||||
//~| ERROR type parameter `_T` is unused
|
||||
}
|
@ -0,0 +1,67 @@
|
||||
error: free type alias without body
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:4:5
|
||||
|
|
||||
LL | type A: Ord;
|
||||
| ^^^^^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the type: `= <type>;`
|
||||
|
||||
error: bounds on `type`s in this context have no effect
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:4:13
|
||||
|
|
||||
LL | type A: Ord;
|
||||
| ^^^
|
||||
|
||||
error: bounds on `type`s in this context have no effect
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:7:13
|
||||
|
|
||||
LL | type B: Ord = u8;
|
||||
| ^^^
|
||||
|
||||
error: bounds on `type`s in this context have no effect
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:9:13
|
||||
|
|
||||
LL | type C: Ord where 'static: 'static = u8;
|
||||
| ^^^
|
||||
|
||||
error: free type alias without body
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:11:5
|
||||
|
|
||||
LL | type D<_T>: Ord;
|
||||
| ^^^^^^^^^^^^^^^-
|
||||
| |
|
||||
| help: provide a definition for the type: `= <type>;`
|
||||
|
||||
error: bounds on `type`s in this context have no effect
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:11:17
|
||||
|
|
||||
LL | type D<_T>: Ord;
|
||||
| ^^^
|
||||
|
||||
error: bounds on `type`s in this context have no effect
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:14:17
|
||||
|
|
||||
LL | type E<_T>: Ord = u8;
|
||||
| ^^^
|
||||
|
||||
error: bounds on `type`s in this context have no effect
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:17:17
|
||||
|
|
||||
LL | type F<_T>: Ord where 'static: 'static = u8;
|
||||
| ^^^
|
||||
|
||||
error[E0091]: type parameter `_T` is unused
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:14:12
|
||||
|
|
||||
LL | type E<_T>: Ord = u8;
|
||||
| ^^ unused type parameter
|
||||
|
||||
error[E0091]: type parameter `_T` is unused
|
||||
--> $DIR/item-free-type-bounds-semantic-fail.rs:17:12
|
||||
|
|
||||
LL | type F<_T>: Ord where 'static: 'static = u8;
|
||||
| ^^ unused type parameter
|
||||
|
||||
error: aborting due to 10 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0091`.
|
13
src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs
Normal file
13
src/test/ui/parser/item-free-type-bounds-syntactic-pass.rs
Normal file
@ -0,0 +1,13 @@
|
||||
// check-pass
|
||||
|
||||
fn main() {}
|
||||
|
||||
#[cfg(FALSE)]
|
||||
fn syntax() {
|
||||
type A: Ord;
|
||||
type B: Ord = u8;
|
||||
type C: Ord where 'static: 'static = u8;
|
||||
type D<_T>: Ord;
|
||||
type E<_T>: Ord = u8;
|
||||
type F<_T>: Ord where 'static: 'static = u8;
|
||||
}
|
Loading…
Reference in New Issue
Block a user