Skip to content

Rollup of 9 pull requests #109284

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 23 commits into from
Mar 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
60da5de
Fix index out of bounds in suggest_trait_fn_ty_for_impl_fn_infer
compiler-errors Mar 16, 2023
dc39bf8
E0206 - added `union` to description
mili-l Mar 16, 2023
1f12c3e
E0206 - removed space
mili-l Mar 16, 2023
827a990
Do not ICE for unexpected lifetime with ConstGeneric rib
chenyukang Mar 16, 2023
2dbda0a
fallback to lstat when stat fails on Windows
chaitanyav Mar 16, 2023
0aad0b3
run rustfmt on changes
chaitanyav Mar 17, 2023
550e308
Suggest surrounding the macro with `{}` to interpret as a statement
mu001999 Mar 17, 2023
97740a6
Check for llvm-tools before install
chaitanyav Mar 17, 2023
2a52080
resolve: Improve debug impls for `NameBinding`
petrochenkov Mar 17, 2023
05dc132
E0206 - code review changes
mili-l Mar 17, 2023
c4bb47a
Update compiler/rustc_error_codes/src/error_codes/E0206.md
mili-l Mar 17, 2023
79ad7cc
Erase escaping late-bound regions when probing for ambiguous associat…
compiler-errors Mar 13, 2023
08c9132
Pass the right HIR back from get_fn_decl
compiler-errors Mar 17, 2023
32c589b
Modify code style as per comments
chaitanyav Mar 17, 2023
0ee7539
Rollup merge of #109102 - compiler-errors:ambig-assoc-in-non-lt-binde…
matthiaskrgr Mar 17, 2023
55d5cd5
Rollup merge of #109200 - compiler-errors:issue-109191, r=WaffleLapkin
matthiaskrgr Mar 17, 2023
e7d6369
Rollup merge of #109211 - mili-l:mili_l/update_e0206_description, r=W…
matthiaskrgr Mar 17, 2023
dfd2b64
Rollup merge of #109222 - chenyukang:yukang/fix-109143, r=petrochenkov
matthiaskrgr Mar 17, 2023
2a3c0e3
Rollup merge of #109235 - chaitanyav:master, r=ChrisDenton
matthiaskrgr Mar 17, 2023
d91858b
Rollup merge of #109248 - compiler-errors:get_fn_decl-aaa, r=WaffleLa…
matthiaskrgr Mar 17, 2023
7e5705e
Rollup merge of #109251 - MU001999:master, r=Nilstrieb
matthiaskrgr Mar 17, 2023
01edab6
Rollup merge of #109256 - chaitanyav:fix_108948, r=albertlarsan68
matthiaskrgr Mar 17, 2023
0d4a56c
Rollup merge of #109257 - petrochenkov:bindebug, r=WaffleLapkin
matthiaskrgr Mar 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/rustc_error_codes/src/error_codes/E0206.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
The `Copy` trait was implemented on a type which is neither a struct nor an
enum.
The `Copy` trait was implemented on a type which is neither a struct, an
enum, nor a union.

Erroneous code example:

Expand All @@ -10,6 +10,6 @@ struct Bar;
impl Copy for &'static mut Bar { } // error!
```

You can only implement `Copy` for a struct or an enum.
You can only implement `Copy` for a struct, an enum, or a union.
The previous example will fail because `&'static mut Bar`
is not a struct or enum.
is not a struct, an enum, or a union.
24 changes: 18 additions & 6 deletions compiler/rustc_expand/src/mbe/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,12 +245,24 @@ pub(super) fn emit_frag_parse_err(
e.note(
"the macro call doesn't expand to an expression, but it can expand to a statement",
);
e.span_suggestion_verbose(
site_span.shrink_to_hi(),
"add `;` to interpret the expansion as a statement",
";",
Applicability::MaybeIncorrect,
);

if parser.token == token::Semi {
if let Ok(snippet) = parser.sess.source_map().span_to_snippet(site_span) {
e.span_suggestion_verbose(
site_span,
"surround the macro invocation with `{}` to interpret the expansion as a statement",
format!("{{ {}; }}", snippet),
Applicability::MaybeIncorrect,
);
}
} else {
e.span_suggestion_verbose(
site_span.shrink_to_hi(),
"add `;` to interpret the expansion as a statement",
";",
Applicability::MaybeIncorrect,
);
}
}
},
_ => annotate_err_with_kind(&mut e, kind, site_span),
Expand Down
26 changes: 20 additions & 6 deletions compiler/rustc_hir_analysis/src/astconv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2396,13 +2396,24 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx,
infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id),
);
// I guess we don't need to make a universe unless we need it,
// but also we're on the error path, so it doesn't matter here.
let universe = infcx.create_next_universe();
infcx
.can_eq(
ty::ParamEnv::empty(),
impl_.self_ty(),
// Must fold past escaping bound vars too,
// since we have those at this point in astconv.
tcx.fold_regions(qself_ty, |_, _| tcx.lifetimes.re_erased),
tcx.replace_escaping_bound_vars_uncached(qself_ty, ty::fold::FnMutDelegate {
regions: &mut |_| tcx.lifetimes.re_erased,
types: &mut |bv| tcx.mk_placeholder(ty::PlaceholderType {
universe,
name: bv.kind,
}),
consts: &mut |bv, ty| tcx.mk_const(ty::PlaceholderConst {
universe,
name: bv
}, ty),
})
)
})
&& tcx.impl_polarity(impl_def_id) != ty::ImplPolarity::Negative
Expand Down Expand Up @@ -3317,10 +3328,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
tcx,
trait_ref.substs.extend_to(tcx, assoc.def_id, |param, _| tcx.mk_param_from_def(param)),
);
let fn_sig = tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), fn_sig);

let ty = if let Some(arg_idx) = arg_idx { fn_sig.input(arg_idx) } else { fn_sig.output() };

Some(tcx.liberate_late_bound_regions(fn_hir_id.expect_owner().to_def_id(), ty))
Some(if let Some(arg_idx) = arg_idx {
*fn_sig.inputs().get(arg_idx)?
} else {
fn_sig.output()
})
}

#[instrument(level = "trace", skip(self, generate_err))]
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
{
// check that the `if` expr without `else` is the fn body's expr
if expr.span == sp {
return self.get_fn_decl(hir_id).and_then(|(fn_decl, _)| {
return self.get_fn_decl(hir_id).and_then(|(_, fn_decl, _)| {
let span = fn_decl.output.span();
let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
Some((span, format!("expected `{snippet}` because of this return type")))
Expand Down
19 changes: 7 additions & 12 deletions compiler/rustc_hir_typeck/src/coercion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1722,20 +1722,21 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fcx.suggest_semicolon_at_end(cond_expr.span, &mut err);
}
}
fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
fcx.get_node_fn_decl(parent)
.map(|(fn_id, fn_decl, _, is_main)| (fn_id, fn_decl, is_main))
} else {
fcx.get_fn_decl(parent_id)
};

if let Some((fn_decl, can_suggest)) = fn_decl {
if let Some((fn_id, fn_decl, can_suggest)) = fn_decl {
if blk_id.is_none() {
pointing_at_return_type |= fcx.suggest_missing_return_type(
&mut err,
&fn_decl,
expected,
found,
can_suggest,
fcx.tcx.hir().get_parent_item(id).into(),
fn_id,
);
}
if !pointing_at_return_type {
Expand All @@ -1746,17 +1747,11 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let parent_id = fcx.tcx.hir().get_parent_item(id);
let parent_item = fcx.tcx.hir().get_by_def_id(parent_id.def_id);

if let (Some(expr), Some(_), Some((fn_decl, _, _))) =
if let (Some(expr), Some(_), Some((fn_id, fn_decl, _, _))) =
(expression, blk_id, fcx.get_node_fn_decl(parent_item))
{
fcx.suggest_missing_break_or_return_expr(
&mut err,
expr,
fn_decl,
expected,
found,
id,
parent_id.into(),
&mut err, expr, fn_decl, expected, found, id, fn_id,
);
}

Expand Down Expand Up @@ -1882,7 +1877,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
}

fn is_return_ty_unsized<'a>(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool {
if let Some((fn_decl, _)) = fcx.get_fn_decl(blk_id)
if let Some((_, fn_decl, _)) = fcx.get_fn_decl(blk_id)
&& let hir::FnRetTy::Return(ty) = fn_decl.output
&& let ty = fcx.astconv().ast_ty_to_ty( ty)
&& let ty::Dynamic(..) = ty.kind()
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -788,7 +788,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.ret_coercion_span.set(Some(expr.span));
}
let cause = self.cause(expr.span, ObligationCauseCode::ReturnNoExpression);
if let Some((fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
if let Some((_, fn_decl, _)) = self.get_fn_decl(expr.hir_id) {
coercion.coerce_forced_unit(
self,
&cause,
Expand Down
61 changes: 42 additions & 19 deletions compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -898,51 +898,74 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
)
}

/// Given a function `Node`, return its `FnDecl` if it exists, or `None` otherwise.
/// Given a function `Node`, return its `HirId` and `FnDecl` if it exists. Given a closure
/// that is the child of a function, return that function's `HirId` and `FnDecl` instead.
/// This may seem confusing at first, but this is used in diagnostics for `async fn`,
/// for example, where most of the type checking actually happens within a nested closure,
/// but we often want access to the parent function's signature.
///
/// Otherwise, return false.
pub(in super::super) fn get_node_fn_decl(
&self,
node: Node<'tcx>,
) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident, bool)> {
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, Ident, bool)> {
match node {
Node::Item(&hir::Item { ident, kind: hir::ItemKind::Fn(ref sig, ..), .. }) => {
Node::Item(&hir::Item {
ident,
kind: hir::ItemKind::Fn(ref sig, ..),
owner_id,
..
}) => {
// This is less than ideal, it will not suggest a return type span on any
// method called `main`, regardless of whether it is actually the entry point,
// but it will still present it as the reason for the expected type.
Some((&sig.decl, ident, ident.name != sym::main))
Some((
hir::HirId::make_owner(owner_id.def_id),
&sig.decl,
ident,
ident.name != sym::main,
))
}
Node::TraitItem(&hir::TraitItem {
ident,
kind: hir::TraitItemKind::Fn(ref sig, ..),
owner_id,
..
}) => Some((&sig.decl, ident, true)),
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, true)),
Node::ImplItem(&hir::ImplItem {
ident,
kind: hir::ImplItemKind::Fn(ref sig, ..),
owner_id,
..
}) => Some((&sig.decl, ident, false)),
Node::Expr(&hir::Expr {
hir_id,
kind: hir::ExprKind::Closure(..),
..
}) if let Some(Node::Item(&hir::Item {
}) => Some((hir::HirId::make_owner(owner_id.def_id), &sig.decl, ident, false)),
Node::Expr(&hir::Expr { hir_id, kind: hir::ExprKind::Closure(..), .. })
if let Some(Node::Item(&hir::Item {
ident,
kind: hir::ItemKind::Fn(ref sig, ..),
owner_id,
..
})) = self.tcx.hir().find_parent(hir_id) => Some((
hir::HirId::make_owner(owner_id.def_id),
&sig.decl,
ident,
kind: hir::ItemKind::Fn(ref sig, ..),
..
})) = self.tcx.hir().find_parent(hir_id) => {
Some((&sig.decl, ident, ident.name != sym::main))
},
ident.name != sym::main,
)),
_ => None,
}
}

/// Given a `HirId`, return the `FnDecl` of the method it is enclosed by and whether a
/// Given a `HirId`, return the `HirId` of the enclosing function, its `FnDecl`, and whether a
/// suggestion can be made, `None` otherwise.
pub fn get_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, bool)> {
pub fn get_fn_decl(
&self,
blk_id: hir::HirId,
) -> Option<(hir::HirId, &'tcx hir::FnDecl<'tcx>, bool)> {
// Get enclosing Fn, if it is a function or a trait method, unless there's a `loop` or
// `while` before reaching it, as block tail returns are not available in them.
self.tcx.hir().get_return_block(blk_id).and_then(|blk_id| {
let parent = self.tcx.hir().get(blk_id);
self.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
self.get_node_fn_decl(parent)
.map(|(fn_id, fn_decl, _, is_main)| (fn_id, fn_decl, is_main))
})
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1669,7 +1669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Given a function block's `HirId`, returns its `FnDecl` if it exists, or `None` otherwise.
fn get_parent_fn_decl(&self, blk_id: hir::HirId) -> Option<(&'tcx hir::FnDecl<'tcx>, Ident)> {
let parent = self.tcx.hir().get_by_def_id(self.tcx.hir().get_parent_item(blk_id).def_id);
self.get_node_fn_decl(parent).map(|(fn_decl, ident, _)| (fn_decl, ident))
self.get_node_fn_decl(parent).map(|(_, fn_decl, ident, _)| (fn_decl, ident))
}

/// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
Expand Down
3 changes: 1 addition & 2 deletions compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let expr = expr.peel_drop_temps();
self.suggest_missing_semicolon(err, expr, expected, false);
let mut pointing_at_return_type = false;
if let Some((fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
let fn_id = self.tcx.hir().get_return_block(blk_id).unwrap();
if let Some((fn_id, fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
pointing_at_return_type = self.suggest_missing_return_type(
err,
&fn_decl,
Expand Down
16 changes: 12 additions & 4 deletions compiler/rustc_resolve/src/imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,28 @@ impl<'a> std::fmt::Debug for ImportKind<'a> {
Single {
ref source,
ref target,
ref source_bindings,
ref target_bindings,
ref type_ns_only,
ref nested,
ref id,
// Ignore the following to avoid an infinite loop while printing.
source_bindings: _,
target_bindings: _,
} => f
.debug_struct("Single")
.field("source", source)
.field("target", target)
// Ignore the nested bindings to avoid an infinite loop while printing.
.field(
"source_bindings",
&source_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
)
.field(
"target_bindings",
&target_bindings.clone().map(|b| b.into_inner().map(|_| format_args!(".."))),
)
.field("type_ns_only", type_ns_only)
.field("nested", nested)
.field("id", id)
.finish_non_exhaustive(),
.finish(),
Glob { ref is_prelude, ref max_vis, ref id } => f
.debug_struct("Glob")
.field("is_prelude", is_prelude)
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_resolve/src/late.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1478,8 +1478,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
} else {
LifetimeUseSet::Many
}),
LifetimeRibKind::Generics { .. } => None,
LifetimeRibKind::ConstGeneric | LifetimeRibKind::AnonConst => {
LifetimeRibKind::Generics { .. }
| LifetimeRibKind::ConstGeneric => None,
LifetimeRibKind::AnonConst => {
span_bug!(ident.span, "unexpected rib kind: {:?}", rib.kind)
}
})
Expand Down
12 changes: 11 additions & 1 deletion library/std/src/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1236,7 +1236,17 @@ pub fn link(_original: &Path, _link: &Path) -> io::Result<()> {
}

pub fn stat(path: &Path) -> io::Result<FileAttr> {
metadata(path, ReparsePoint::Follow)
match metadata(path, ReparsePoint::Follow) {
Err(err) if err.raw_os_error() == Some(c::ERROR_CANT_ACCESS_FILE as i32) => {
if let Ok(attrs) = lstat(path) {
if !attrs.file_type().is_symlink() {
return Ok(attrs);
}
}
Err(err)
}
result => result,
}
}

pub fn lstat(path: &Path) -> io::Result<FileAttr> {
Expand Down
11 changes: 7 additions & 4 deletions src/bootstrap/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,10 +210,13 @@ install!((self, builder, _config),
}
};
LlvmTools, alias = "llvm-tools", Self::should_build(_config), only_hosts: true, {
let tarball = builder
.ensure(dist::LlvmTools { target: self.target })
.expect("missing llvm-tools");
install_sh(builder, "llvm-tools", self.compiler.stage, Some(self.target), &tarball);
if let Some(tarball) = builder.ensure(dist::LlvmTools { target: self.target }) {
install_sh(builder, "llvm-tools", self.compiler.stage, Some(self.target), &tarball);
} else {
builder.info(
&format!("skipping llvm-tools stage{} ({}): external LLVM", self.compiler.stage, self.target),
);
}
};
Rustfmt, alias = "rustfmt", Self::should_build(_config), only_hosts: true, {
if let Some(tarball) = builder.ensure(dist::Rustfmt {
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/lifetimes/unusual-rib-combinations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ fn d<const C: S>() {}
//~^ ERROR missing lifetime specifier
//~| ERROR `S<'_>` is forbidden as the type of a const generic parameter

trait Foo<'a> {}
struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
//~^ ERROR use of non-static lifetime `'a` in const generic
//~| ERROR `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter

fn main() {}
Loading