Skip to content
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

Rollup of 10 pull requests #96785

Merged
merged 31 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
e626634
Collect function instance used in `global_asm!` sym operand
tmiasko May 2, 2022
bf4d7fa
Hide InlineConst's generic arg during print
nbdd0121 Apr 29, 2022
6baaa52
Allow inline consts to reference generic params
nbdd0121 Apr 29, 2022
5b5ac28
Bless clippy error msg
nbdd0121 May 5, 2022
6c8a2d4
rustdoc: when running a function-signature search, tweak the tab bar
notriddle Apr 30, 2022
345a580
Use STARTS_WITH, since it's more specific
notriddle May 1, 2022
21a1213
rustdoc: change the "In Function Signatures" to context-sensitive
notriddle May 2, 2022
8b2147b
rustdoc: fix keyboard shortcuts and console log on search page
notriddle May 2, 2022
75790fa
rustdoc: add test case assertions for ArrowDown highlight first result
notriddle May 3, 2022
4c183cd
rustdoc: fix JS error when rendering parse error
notriddle May 3, 2022
30309db
Put the 2229 migration errors in alphabetical order
scottmcm May 4, 2022
20010d7
rustdoc: ensure HTML/JS side implementors don't have dups
notriddle May 6, 2022
903aebe
Fix test case checking for where the JS goes
notriddle May 6, 2022
8ff0189
turn `append_place_to_string` from recursion into iteration
SparrowLii May 6, 2022
279dee5
Fix reexports missing from the search index
GuillaumeGomez May 5, 2022
fb2f97a
Add GUI test for search reexports
GuillaumeGomez May 5, 2022
bd11e22
Add missing newline
notriddle May 6, 2022
857eb02
suggest fully qualified path with appropriate params
TaKO8Ki May 6, 2022
85e688e
Fix comment for async closure variant
liuw May 6, 2022
fcb385c
Use matches! for YieldSource::is_await
liuw May 6, 2022
a87fa63
`mirror_expr` cleanup
lcnr May 6, 2022
66443a1
Rollup merge of #96557 - nbdd0121:const, r=oli-obk
GuillaumeGomez May 6, 2022
fcb0bce
Rollup merge of #96590 - notriddle:notriddle/tab-bar-fn-search, r=Gui…
GuillaumeGomez May 6, 2022
c7af4e6
Rollup merge of #96650 - tmiasko:global-asm-sym-fn, r=Amanieu
GuillaumeGomez May 6, 2022
c3ddd59
Rollup merge of #96733 - SparrowLii:place_to_string, r=davidtwco
GuillaumeGomez May 6, 2022
93b86d6
Rollup merge of #96748 - GuillaumeGomez:reexports-in-search, r=notriddle
GuillaumeGomez May 6, 2022
28d85ab
Rollup merge of #96752 - scottmcm:error-sorting, r=compiler-errors
GuillaumeGomez May 6, 2022
bcfb95a
Rollup merge of #96754 - notriddle:notriddle/impl-dups, r=GuillaumeGomez
GuillaumeGomez May 6, 2022
6db969e
Rollup merge of #96772 - TaKO8Ki:suggest-fully-qualified-path-with-ap…
GuillaumeGomez May 6, 2022
a411a32
Rollup merge of #96776 - liuw:hir, r=oli-obk
GuillaumeGomez May 6, 2022
a0e2c7e
Rollup merge of #96782 - lcnr:mirror-expr, r=compiler-errors
GuillaumeGomez May 6, 2022
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
210 changes: 78 additions & 132 deletions compiler/rustc_borrowck/src/diagnostics/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
//! Borrow checker diagnostics.

use itertools::Itertools;
use rustc_const_eval::util::{call_kind, CallDesugaringKind};
use rustc_errors::{Applicability, Diagnostic};
use rustc_hir as hir;
Expand Down Expand Up @@ -161,158 +162,103 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
}

/// End-user visible description of `place` if one can be found.
/// If the place is a temporary for instance, None will be returned.
/// If the place is a temporary for instance, `None` will be returned.
pub(super) fn describe_place(&self, place_ref: PlaceRef<'tcx>) -> Option<String> {
self.describe_place_with_options(place_ref, IncludingDowncast(false))
}

/// End-user visible description of `place` if one can be found. If the
/// place is a temporary for instance, None will be returned.
/// `IncludingDowncast` parameter makes the function return `Err` if `ProjectionElem` is
/// End-user visible description of `place` if one can be found. If the place is a temporary
/// for instance, `None` will be returned.
/// `IncludingDowncast` parameter makes the function return `None` if `ProjectionElem` is
/// `Downcast` and `IncludingDowncast` is true
pub(super) fn describe_place_with_options(
&self,
place: PlaceRef<'tcx>,
including_downcast: IncludingDowncast,
) -> Option<String> {
let local = place.local;
let mut autoderef_index = None;
let mut buf = String::new();
match self.append_place_to_string(place, &mut buf, false, &including_downcast) {
Ok(()) => Some(buf),
Err(()) => None,
}
}

/// Appends end-user visible description of `place` to `buf`.
fn append_place_to_string(
&self,
place: PlaceRef<'tcx>,
buf: &mut String,
mut autoderef: bool,
including_downcast: &IncludingDowncast,
) -> Result<(), ()> {
match place {
PlaceRef { local, projection: [] } => {
self.append_local_to_string(local, buf)?;
}
PlaceRef { local, projection: [ProjectionElem::Deref] }
if self.body.local_decls[local].is_ref_for_guard() =>
{
self.append_place_to_string(
PlaceRef { local, projection: &[] },
buf,
autoderef,
&including_downcast,
)?;
}
PlaceRef { local, projection: [ProjectionElem::Deref] }
if self.body.local_decls[local].is_ref_to_static() =>
{
let local_info = &self.body.local_decls[local].local_info;
if let Some(box LocalInfo::StaticRef { def_id, .. }) = *local_info {
buf.push_str(self.infcx.tcx.item_name(def_id).as_str());
} else {
unreachable!();
}
}
PlaceRef { local, projection: [proj_base @ .., elem] } => {
match elem {
ProjectionElem::Deref => {
let upvar_field_projection = self.is_upvar_field_projection(place);
if let Some(field) = upvar_field_projection {
let var_index = field.index();
let name = self.upvars[var_index].place.to_string(self.infcx.tcx);
if self.upvars[var_index].by_ref {
buf.push_str(&name);
} else {
buf.push('*');
buf.push_str(&name);
}
} else {
if autoderef {
// FIXME turn this recursion into iteration
self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
autoderef,
&including_downcast,
)?;
} else {
buf.push('*');
self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
autoderef,
&including_downcast,
)?;
}
let mut ok = self.append_local_to_string(local, &mut buf);

for (index, elem) in place.projection.into_iter().enumerate() {
match elem {
ProjectionElem::Deref => {
if index == 0 {
if self.body.local_decls[local].is_ref_for_guard() {
continue;
}
}
ProjectionElem::Downcast(..) => {
self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
autoderef,
&including_downcast,
)?;
if including_downcast.0 {
return Err(());
if let Some(box LocalInfo::StaticRef { def_id, .. }) =
&self.body.local_decls[local].local_info
{
buf.push_str(self.infcx.tcx.item_name(*def_id).as_str());
ok = Ok(());
continue;
}
}
ProjectionElem::Field(field, _ty) => {
autoderef = true;

// FIXME(project-rfc_2229#36): print capture precisely here.
let upvar_field_projection = self.is_upvar_field_projection(place);
if let Some(field) = upvar_field_projection {
let var_index = field.index();
let name = self.upvars[var_index].place.to_string(self.infcx.tcx);
buf.push_str(&name);
} else {
let field_name = self
.describe_field(PlaceRef { local, projection: proj_base }, *field);
self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
autoderef,
&including_downcast,
)?;
buf.push('.');
buf.push_str(&field_name);
if let Some(field) = self.is_upvar_field_projection(PlaceRef {
local,
projection: place.projection.split_at(index + 1).0,
}) {
let var_index = field.index();
buf = self.upvars[var_index].place.to_string(self.infcx.tcx);
ok = Ok(());
if !self.upvars[var_index].by_ref {
buf.insert(0, '*');
}
}
ProjectionElem::Index(index) => {
autoderef = true;

self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
autoderef,
&including_downcast,
)?;
buf.push('[');
if self.append_local_to_string(*index, buf).is_err() {
buf.push('_');
} else {
if autoderef_index.is_none() {
autoderef_index =
match place.projection.into_iter().rev().find_position(|elem| {
!matches!(
elem,
ProjectionElem::Deref | ProjectionElem::Downcast(..)
)
}) {
Some((index, _)) => Some(place.projection.len() - index),
None => Some(0),
};
}
if index >= autoderef_index.unwrap() {
buf.insert(0, '*');
}
buf.push(']');
}
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
autoderef = true;
// Since it isn't possible to borrow an element on a particular index and
// then use another while the borrow is held, don't output indices details
// to avoid confusing the end-user
self.append_place_to_string(
PlaceRef { local, projection: proj_base },
buf,
autoderef,
&including_downcast,
)?;
buf.push_str("[..]");
}
ProjectionElem::Downcast(..) if including_downcast.0 => return None,
ProjectionElem::Downcast(..) => (),
ProjectionElem::Field(field, _ty) => {
// FIXME(project-rfc_2229#36): print capture precisely here.
if let Some(field) = self.is_upvar_field_projection(PlaceRef {
local,
projection: place.projection.split_at(index + 1).0,
}) {
buf = self.upvars[field.index()].place.to_string(self.infcx.tcx);
ok = Ok(());
} else {
let field_name = self.describe_field(
PlaceRef { local, projection: place.projection.split_at(index).0 },
*field,
);
buf.push('.');
buf.push_str(&field_name);
}
};
}
ProjectionElem::Index(index) => {
buf.push('[');
if self.append_local_to_string(*index, &mut buf).is_err() {
buf.push('_');
}
buf.push(']');
}
ProjectionElem::ConstantIndex { .. } | ProjectionElem::Subslice { .. } => {
// Since it isn't possible to borrow an element on a particular index and
// then use another while the borrow is held, don't output indices details
// to avoid confusing the end-user
buf.push_str("[..]");
}
}
}

Ok(())
ok.ok().map(|_| buf)
}

/// Appends end-user visible description of the `local` place to `buf`. If `local` doesn't have
Expand Down
7 changes: 2 additions & 5 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1441,7 +1441,7 @@ pub enum AsyncGeneratorKind {
/// An explicit `async` block written by the user.
Block,

/// An explicit `async` block written by the user.
/// An explicit `async` closure written by the user.
Closure,

/// The `async` block generated as the body of an async function.
Expand Down Expand Up @@ -2078,10 +2078,7 @@ pub enum YieldSource {

impl YieldSource {
pub fn is_await(&self) -> bool {
match self {
YieldSource::Await { .. } => true,
YieldSource::Yield => false,
}
matches!(self, YieldSource::Await { .. })
}
}

Expand Down
23 changes: 22 additions & 1 deletion compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -731,6 +731,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// | help: specify type like: `<Impl as Into<u32>>::into(foo_impl)`
// |
// = note: cannot satisfy `Impl: Into<_>`
debug!(?segment);
if !impl_candidates.is_empty() && e.span.contains(span)
&& let Some(expr) = exprs.first()
&& let ExprKind::Path(hir::QPath::Resolved(_, path)) = expr.kind
Expand All @@ -739,9 +740,29 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let mut eraser = TypeParamEraser(self.tcx);
let candidate_len = impl_candidates.len();
let mut suggestions: Vec<_> = impl_candidates.iter().map(|candidate| {
let trait_item = self.tcx
.associated_items(candidate.def_id)
.find_by_name_and_kind(
self.tcx,
segment.ident,
ty::AssocKind::Fn,
candidate.def_id
);
let prefix = if let Some(trait_item) = trait_item
&& let Some(trait_m) = trait_item.def_id.as_local()
&& let hir::TraitItemKind::Fn(fn_, _) = &self.tcx.hir().trait_item(hir::TraitItemId { def_id: trait_m }).kind
{
match fn_.decl.implicit_self {
hir::ImplicitSelfKind::ImmRef => "&",
hir::ImplicitSelfKind::MutRef => "&mut ",
_ => "",
}
} else {
""
};
let candidate = candidate.super_fold_with(&mut eraser);
vec![
(expr.span.shrink_to_lo(), format!("{}::{}(", candidate, segment.ident)),
(expr.span.shrink_to_lo(), format!("{}::{}({}", candidate, segment.ident, prefix)),
if exprs.len() == 1 {
(expr.span.shrink_to_hi().with_hi(e.span.hi()), ")".to_string())
} else {
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/ty/print/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ pub trait Printer<'tcx>: Sized {
match key.disambiguated_data.data {
// Closures' own generics are only captures, don't print them.
DefPathData::ClosureExpr => {}
// This covers both `DefKind::AnonConst` and `DefKind::InlineConst`.
// Anon consts doesn't have their own generics, and inline consts' own
// generics are their inferred types, so don't print them.
DefPathData::AnonConst => {}

// If we have any generic arguments to print, we do that
// on top of the same path, but without its own generics.
Expand Down
Loading