Auto merge of #83225 - JohnTitor:rollup-4hnuhb8, r=JohnTitor
Rollup of 8 pull requests Successful merges: - #82774 (Fix bad diagnostics for anon params with ref and/or qualified paths) - #82826 ((std::net::parser): Fix capitalization of IP version names) - #83092 (More precise spans for HIR paths) - #83124 (Do not insert impl_trait_in_bindings opaque definitions twice.) - #83202 (Show details in cfg version unstable book) - #83203 (Don't warn about old rustdoc lint names (temporarily)) - #83206 (Update books) - #83219 (Update cargo) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2c7490379d
51 changed files with 351 additions and 225 deletions
|
@ -149,9 +149,17 @@ impl PathSegment {
|
|||
pub fn from_ident(ident: Ident) -> Self {
|
||||
PathSegment { ident, id: DUMMY_NODE_ID, args: None }
|
||||
}
|
||||
|
||||
pub fn path_root(span: Span) -> Self {
|
||||
PathSegment::from_ident(Ident::new(kw::PathRoot, span))
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
match &self.args {
|
||||
Some(args) => self.ident.span.to(args.span()),
|
||||
None => self.ident.span,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The arguments of a path segment.
|
||||
|
|
|
@ -438,31 +438,6 @@ impl<'a> TokenStreamLowering<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
struct ImplTraitTypeIdVisitor<'a> {
|
||||
ids: &'a mut SmallVec<[NodeId; 1]>,
|
||||
}
|
||||
|
||||
impl Visitor<'_> for ImplTraitTypeIdVisitor<'_> {
|
||||
fn visit_ty(&mut self, ty: &Ty) {
|
||||
match ty.kind {
|
||||
TyKind::Typeof(_) | TyKind::BareFn(_) => return,
|
||||
|
||||
TyKind::ImplTrait(id, _) => self.ids.push(id),
|
||||
_ => {}
|
||||
}
|
||||
visit::walk_ty(self, ty);
|
||||
}
|
||||
|
||||
fn visit_path_segment(&mut self, path_span: Span, path_segment: &PathSegment) {
|
||||
if let Some(ref p) = path_segment.args {
|
||||
if let GenericArgs::Parenthesized(_) = **p {
|
||||
return;
|
||||
}
|
||||
}
|
||||
visit::walk_path_segment(self, path_span, path_segment)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||
fn lower_crate(mut self, c: &Crate) -> hir::Crate<'hir> {
|
||||
/// Full-crate AST visitor that inserts into a fresh
|
||||
|
@ -1789,14 +1764,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
)
|
||||
}
|
||||
|
||||
fn lower_local(&mut self, l: &Local) -> (hir::Local<'hir>, SmallVec<[NodeId; 1]>) {
|
||||
let mut ids = SmallVec::<[NodeId; 1]>::new();
|
||||
if self.sess.features_untracked().impl_trait_in_bindings {
|
||||
if let Some(ref ty) = l.ty {
|
||||
let mut visitor = ImplTraitTypeIdVisitor { ids: &mut ids };
|
||||
visitor.visit_ty(ty);
|
||||
}
|
||||
}
|
||||
fn lower_local(&mut self, l: &Local) -> hir::Local<'hir> {
|
||||
let ty = l.ty.as_ref().map(|t| {
|
||||
let mut capturable_lifetimes;
|
||||
self.lower_ty(
|
||||
|
@ -1815,17 +1783,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let init = l.init.as_ref().map(|e| self.lower_expr(e));
|
||||
let hir_id = self.lower_node_id(l.id);
|
||||
self.lower_attrs(hir_id, &l.attrs);
|
||||
(
|
||||
hir::Local {
|
||||
hir_id,
|
||||
ty,
|
||||
pat: self.lower_pat(&l.pat),
|
||||
init,
|
||||
span: l.span,
|
||||
source: hir::LocalSource::Normal,
|
||||
},
|
||||
ids,
|
||||
)
|
||||
hir::Local {
|
||||
hir_id,
|
||||
ty,
|
||||
pat: self.lower_pat(&l.pat),
|
||||
init,
|
||||
span: l.span,
|
||||
source: hir::LocalSource::Normal,
|
||||
}
|
||||
}
|
||||
|
||||
fn lower_fn_params_to_names(&mut self, decl: &FnDecl) -> &'hir [Ident] {
|
||||
|
@ -2445,27 +2410,14 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
fn lower_stmt(&mut self, s: &Stmt) -> SmallVec<[hir::Stmt<'hir>; 1]> {
|
||||
let (hir_id, kind) = match s.kind {
|
||||
StmtKind::Local(ref l) => {
|
||||
let (l, item_ids) = self.lower_local(l);
|
||||
let mut ids: SmallVec<[hir::Stmt<'hir>; 1]> = item_ids
|
||||
.into_iter()
|
||||
.map(|item_id| {
|
||||
let item_id = hir::ItemId {
|
||||
// All the items that `lower_local` finds are `impl Trait` types.
|
||||
def_id: self.lower_node_id(item_id).expect_owner(),
|
||||
};
|
||||
self.stmt(s.span, hir::StmtKind::Item(item_id))
|
||||
})
|
||||
.collect();
|
||||
let l = self.lower_local(l);
|
||||
let hir_id = self.lower_node_id(s.id);
|
||||
self.alias_attrs(hir_id, l.hir_id);
|
||||
ids.push({
|
||||
hir::Stmt {
|
||||
hir_id,
|
||||
kind: hir::StmtKind::Local(self.arena.alloc(l)),
|
||||
span: s.span,
|
||||
}
|
||||
});
|
||||
return ids;
|
||||
return smallvec![hir::Stmt {
|
||||
hir_id,
|
||||
kind: hir::StmtKind::Local(self.arena.alloc(l)),
|
||||
span: s.span,
|
||||
}];
|
||||
}
|
||||
StmtKind::Item(ref it) => {
|
||||
// Can only use the ID once.
|
||||
|
|
|
@ -30,6 +30,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
let partial_res =
|
||||
self.resolver.get_partial_res(id).unwrap_or_else(|| PartialRes::new(Res::Err));
|
||||
|
||||
let path_span_lo = p.span.shrink_to_lo();
|
||||
let proj_start = p.segments.len() - partial_res.unresolved_segments();
|
||||
let path = self.arena.alloc(hir::Path {
|
||||
res: self.lower_res(partial_res.base_res()),
|
||||
|
@ -108,7 +109,9 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
)
|
||||
},
|
||||
)),
|
||||
span: p.span,
|
||||
span: p.segments[..proj_start]
|
||||
.last()
|
||||
.map_or(path_span_lo, |segment| path_span_lo.to(segment.span())),
|
||||
});
|
||||
|
||||
// Simple case, either no projections, or only fully-qualified.
|
||||
|
@ -127,7 +130,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// e.g., `Vec` in `Vec::new` or `<I as Iterator>::Item` in
|
||||
// `<I as Iterator>::Item::default`.
|
||||
let new_id = self.next_id();
|
||||
self.arena.alloc(self.ty_path(new_id, p.span, hir::QPath::Resolved(qself, path)))
|
||||
self.arena.alloc(self.ty_path(new_id, path.span, hir::QPath::Resolved(qself, path)))
|
||||
};
|
||||
|
||||
// Anything after the base path are associated "extensions",
|
||||
|
@ -141,7 +144,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
// 3. `<<std::vec::Vec<T>>::IntoIter>::Item`
|
||||
// * final path is `<<<std::vec::Vec<T>>::IntoIter>::Item>::clone`
|
||||
for (i, segment) in p.segments.iter().enumerate().skip(proj_start) {
|
||||
let segment = self.arena.alloc(self.lower_path_segment(
|
||||
let hir_segment = self.arena.alloc(self.lower_path_segment(
|
||||
p.span,
|
||||
segment,
|
||||
param_mode,
|
||||
|
@ -150,7 +153,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
itctx.reborrow(),
|
||||
None,
|
||||
));
|
||||
let qpath = hir::QPath::TypeRelative(ty, segment);
|
||||
let qpath = hir::QPath::TypeRelative(ty, hir_segment);
|
||||
|
||||
// It's finished, return the extension of the right node type.
|
||||
if i == p.segments.len() - 1 {
|
||||
|
@ -159,7 +162,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||
|
||||
// Wrap the associated extension in another type node.
|
||||
let new_id = self.next_id();
|
||||
ty = self.arena.alloc(self.ty_path(new_id, p.span, qpath));
|
||||
ty = self.arena.alloc(self.ty_path(new_id, path_span_lo.to(segment.span()), qpath));
|
||||
}
|
||||
|
||||
// We should've returned in the for loop above.
|
||||
|
|
|
@ -1809,7 +1809,7 @@ impl<'hir> QPath<'hir> {
|
|||
pub fn span(&self) -> Span {
|
||||
match *self {
|
||||
QPath::Resolved(_, path) => path.span,
|
||||
QPath::TypeRelative(_, ps) => ps.ident.span,
|
||||
QPath::TypeRelative(qself, ps) => qself.span.to(ps.ident.span),
|
||||
QPath::LangItem(_, span) => span,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ pub fn report_object_safety_error(
|
|||
<https://doc.rust-lang.org/reference/items/traits.html#object-safety>",
|
||||
);
|
||||
|
||||
if tcx.sess.trait_methods_not_found.borrow().contains(&span) {
|
||||
if tcx.sess.trait_methods_not_found.borrow().iter().any(|full_span| full_span.contains(span)) {
|
||||
// Avoid emitting error caused by non-existing method (#58734)
|
||||
err.cancel();
|
||||
}
|
||||
|
|
|
@ -100,6 +100,11 @@ enum TargetLint {
|
|||
/// Lint with this name existed previously, but has been removed/deprecated.
|
||||
/// The string argument is the reason for removal.
|
||||
Removed(String),
|
||||
|
||||
/// A lint name that should give no warnings and have no effect.
|
||||
///
|
||||
/// This is used by rustc to avoid warning about old rustdoc lints before rustdoc registers them as tool lints.
|
||||
Ignored,
|
||||
}
|
||||
|
||||
pub enum FindLintError {
|
||||
|
@ -266,6 +271,33 @@ impl LintStore {
|
|||
}
|
||||
}
|
||||
|
||||
/// This lint should be available with either the old or the new name.
|
||||
///
|
||||
/// Using the old name will not give a warning.
|
||||
/// You must register a lint with the new name before calling this function.
|
||||
#[track_caller]
|
||||
pub fn register_alias(&mut self, old_name: &str, new_name: &str) {
|
||||
let target = match self.by_name.get(new_name) {
|
||||
Some(&Id(lint_id)) => lint_id,
|
||||
_ => bug!("cannot add alias {} for lint {} that does not exist", old_name, new_name),
|
||||
};
|
||||
match self.by_name.insert(old_name.to_string(), Id(target)) {
|
||||
None | Some(Ignored) => {}
|
||||
Some(x) => bug!("duplicate specification of lint {} (was {:?})", old_name, x),
|
||||
}
|
||||
}
|
||||
|
||||
/// This lint should give no warning and have no effect.
|
||||
///
|
||||
/// This is used by rustc to avoid warning about old rustdoc lints before rustdoc registers them as tool lints.
|
||||
#[track_caller]
|
||||
pub fn register_ignored(&mut self, name: &str) {
|
||||
if self.by_name.insert(name.to_string(), Ignored).is_some() {
|
||||
bug!("duplicate specification of lint {}", name);
|
||||
}
|
||||
}
|
||||
|
||||
/// This lint has been renamed; warn about using the new name and apply the lint.
|
||||
#[track_caller]
|
||||
pub fn register_renamed(&mut self, old_name: &str, new_name: &str) {
|
||||
let target = match self.by_name.get(new_name) {
|
||||
|
@ -284,6 +316,7 @@ impl LintStore {
|
|||
Some(&Id(lint_id)) => Ok(vec![lint_id]),
|
||||
Some(&Renamed(_, lint_id)) => Ok(vec![lint_id]),
|
||||
Some(&Removed(_)) => Err(FindLintError::Removed),
|
||||
Some(&Ignored) => Ok(vec![]),
|
||||
None => loop {
|
||||
return match self.lint_groups.get(lint_name) {
|
||||
Some(LintGroup { lint_ids, depr, .. }) => {
|
||||
|
@ -427,6 +460,7 @@ impl LintStore {
|
|||
}
|
||||
},
|
||||
Some(&Id(ref id)) => CheckLintNameResult::Ok(slice::from_ref(id)),
|
||||
Some(&Ignored) => CheckLintNameResult::Ok(&[]),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -340,7 +340,7 @@ fn register_builtins(store: &mut LintStore, no_interleave_lints: bool) {
|
|||
"non_autolinks",
|
||||
];
|
||||
for rustdoc_lint in RUSTDOC_LINTS {
|
||||
store.register_removed(rustdoc_lint, &format!("use `rustdoc::{}` instead", rustdoc_lint));
|
||||
store.register_ignored(rustdoc_lint);
|
||||
}
|
||||
store.register_removed(
|
||||
"intra_doc_link_resolution_failure",
|
||||
|
|
|
@ -52,6 +52,7 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
|
|||
if i >= len {
|
||||
map.extend(repeat(None).take(i - len + 1));
|
||||
}
|
||||
debug_assert!(map[k].is_none());
|
||||
map[k] = Some(v);
|
||||
}
|
||||
|
||||
|
@ -216,9 +217,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
|||
// Overwrite the dummy hash with the real HIR owner hash.
|
||||
nodes.hash = hash;
|
||||
|
||||
// FIXME: feature(impl_trait_in_bindings) broken and trigger this assert
|
||||
//assert!(data.signature.is_none());
|
||||
|
||||
debug_assert!(data.signature.is_none());
|
||||
data.signature =
|
||||
Some(self.arena.alloc(Owner { parent: entry.parent, node: entry.node }));
|
||||
|
||||
|
|
|
@ -640,7 +640,7 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
Err(mut err) => {
|
||||
// We could't parse generic parameters, unlikely to be a turbofish. Rely on
|
||||
// We couldn't parse generic parameters, unlikely to be a turbofish. Rely on
|
||||
// generic parse error instead.
|
||||
err.cancel();
|
||||
*self = snapshot;
|
||||
|
@ -1242,7 +1242,7 @@ impl<'a> Parser<'a> {
|
|||
let is_question = self.eat(&token::Question); // Handle `await? <expr>`.
|
||||
let expr = if self.token == token::OpenDelim(token::Brace) {
|
||||
// Handle `await { <expr> }`.
|
||||
// This needs to be handled separatedly from the next arm to avoid
|
||||
// This needs to be handled separately from the next arm to avoid
|
||||
// interpreting `await { <expr> }?` as `<expr>?.await`.
|
||||
self.parse_block_expr(None, self.token.span, BlockCheckMode::Default, AttrVec::new())
|
||||
} else {
|
||||
|
@ -1613,42 +1613,82 @@ impl<'a> Parser<'a> {
|
|||
Applicability::HasPlaceholders,
|
||||
);
|
||||
return Some(ident);
|
||||
} else if let PatKind::Ident(_, ident, _) = pat.kind {
|
||||
if require_name
|
||||
&& (self.token == token::Comma
|
||||
|| self.token == token::Lt
|
||||
|| self.token == token::CloseDelim(token::Paren))
|
||||
{
|
||||
// `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
|
||||
if first_param {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a `self` type, give it a parameter name",
|
||||
format!("self: {}", ident),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
} else if require_name
|
||||
&& (self.token == token::Comma
|
||||
|| self.token == token::Lt
|
||||
|| self.token == token::CloseDelim(token::Paren))
|
||||
{
|
||||
let rfc_note = "anonymous parameters are removed in the 2018 edition (see RFC 1685)";
|
||||
|
||||
let (ident, self_sugg, param_sugg, type_sugg) = match pat.kind {
|
||||
PatKind::Ident(_, ident, _) => (
|
||||
ident,
|
||||
format!("self: {}", ident),
|
||||
format!("{}: TypeName", ident),
|
||||
format!("_: {}", ident),
|
||||
),
|
||||
// Also catches `fn foo(&a)`.
|
||||
PatKind::Ref(ref pat, mutab)
|
||||
if matches!(pat.clone().into_inner().kind, PatKind::Ident(..)) =>
|
||||
{
|
||||
match pat.clone().into_inner().kind {
|
||||
PatKind::Ident(_, ident, _) => {
|
||||
let mutab = mutab.prefix_str();
|
||||
(
|
||||
ident,
|
||||
format!("self: &{}{}", mutab, ident),
|
||||
format!("{}: &{}TypeName", ident, mutab),
|
||||
format!("_: &{}{}", mutab, ident),
|
||||
)
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
// Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
|
||||
// `fn foo(HashMap: TypeName<u32>)`.
|
||||
if self.token != token::Lt {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a parameter name, give it a type",
|
||||
format!("{}: TypeName", ident),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
_ => {
|
||||
// Otherwise, try to get a type and emit a suggestion.
|
||||
if let Some(ty) = pat.to_ty() {
|
||||
err.span_suggestion_verbose(
|
||||
pat.span,
|
||||
"explicitly ignore the parameter name",
|
||||
format!("_: {}", pprust::ty_to_string(&ty)),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.note(rfc_note);
|
||||
}
|
||||
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
// `fn foo(a, b) {}`, `fn foo(a<x>, b<y>) {}` or `fn foo(usize, usize) {}`
|
||||
if first_param {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a type, explicitly ignore the parameter name",
|
||||
format!("_: {}", ident),
|
||||
Applicability::MachineApplicable,
|
||||
"if this is a `self` type, give it a parameter name",
|
||||
self_sugg,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.note("anonymous parameters are removed in the 2018 edition (see RFC 1685)");
|
||||
|
||||
// Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
|
||||
return if self.token == token::Lt { None } else { Some(ident) };
|
||||
}
|
||||
// Avoid suggesting that `fn foo(HashMap<u32>)` is fixed with a change to
|
||||
// `fn foo(HashMap: TypeName<u32>)`.
|
||||
if self.token != token::Lt {
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a parameter name, give it a type",
|
||||
param_sugg,
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
}
|
||||
err.span_suggestion(
|
||||
pat.span,
|
||||
"if this is a type, explicitly ignore the parameter name",
|
||||
type_sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.note(rfc_note);
|
||||
|
||||
// Don't attempt to recover by using the `X` in `X<Y>` as the parameter name.
|
||||
return if self.token == token::Lt { None } else { Some(ident) };
|
||||
}
|
||||
None
|
||||
}
|
||||
|
|
|
@ -1414,8 +1414,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||
name: Symbol,
|
||||
) {
|
||||
let mut err = struct_span_err!(self.tcx().sess, span, E0223, "ambiguous associated type");
|
||||
if let (Some(_), Ok(snippet)) = (
|
||||
self.tcx().sess.confused_type_with_std_module.borrow().get(&span),
|
||||
if let (true, Ok(snippet)) = (
|
||||
self.tcx()
|
||||
.sess
|
||||
.confused_type_with_std_module
|
||||
.borrow()
|
||||
.keys()
|
||||
.any(|full_span| full_span.contains(span)),
|
||||
self.tcx().sess.source_map().span_to_snippet(span),
|
||||
) {
|
||||
err.span_suggestion(
|
||||
|
|
|
@ -439,7 +439,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
qpath: &QPath<'_>,
|
||||
hir_id: hir::HirId,
|
||||
) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> {
|
||||
let path_span = qpath.qself_span();
|
||||
let path_span = qpath.span();
|
||||
let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, hir_id);
|
||||
let variant = match def {
|
||||
Res::Err => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue