Skip to content

Commit

Permalink
Auto merge of #108015 - matthiaskrgr:rollup-qerohjn, r=matthiaskrgr
Browse files Browse the repository at this point in the history
Rollup of 8 pull requests

Successful merges:

 - #107902 (fix: improve the suggestion on future not awaited)
 - #107913 (Update broken link in cargo style guide)
 - #107942 (Tighter spans for bad inherent `impl` self types)
 - #107948 (Allow shortcuts to directories to be used for ./x.py fmt)
 - #107971 (Clearly document intentional UB in mir-opt tests)
 - #107985 (Added another error to be processed in fallback)
 - #108002 (Update books)
 - #108013 (rustdoc: use a string with one-character codes for search index types)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Feb 13, 2023
2 parents 065852d + f1a3494 commit 5348a89
Show file tree
Hide file tree
Showing 51 changed files with 322 additions and 269 deletions.
33 changes: 17 additions & 16 deletions compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const ADD_ATTR: &str =
"alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items";

impl<'tcx> InherentCollect<'tcx> {
fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId) {
fn check_def_id(&mut self, item: &hir::Item<'_>, self_ty: Ty<'tcx>, def_id: DefId, span: Span) {
let impl_def_id = item.owner_id;
if let Some(def_id) = def_id.as_local() {
// Add the implementation to the mapping from implementation to base
Expand All @@ -76,12 +76,12 @@ impl<'tcx> InherentCollect<'tcx> {
if !self.tcx.has_attr(def_id, sym::rustc_has_incoherent_inherent_impls) {
struct_span_err!(
self.tcx.sess,
item.span,
span,
E0390,
"cannot define inherent `impl` for a type outside of the crate where the type is defined",
)
.help(INTO_DEFINING_CRATE)
.span_help(item.span, ADD_ATTR_TO_TY)
.span_help(span, ADD_ATTR_TO_TY)
.emit();
return;
}
Expand All @@ -93,12 +93,12 @@ impl<'tcx> InherentCollect<'tcx> {
{
struct_span_err!(
self.tcx.sess,
item.span,
span,
E0390,
"cannot define inherent `impl` for a type outside of the crate where the type is defined",
)
.help(INTO_DEFINING_CRATE)
.span_help(impl_item.span, ADD_ATTR)
.span_help(self.tcx.hir().span(impl_item.id.hir_id()), ADD_ATTR)
.emit();
return;
}
Expand All @@ -112,12 +112,12 @@ impl<'tcx> InherentCollect<'tcx> {
} else {
struct_span_err!(
self.tcx.sess,
item.span,
span,
E0116,
"cannot define inherent `impl` for a type outside of the crate \
where the type is defined"
)
.span_label(item.span, "impl for type defined outside of crate.")
.span_label(span, "impl for type defined outside of crate.")
.note("define and implement a trait or new type instead")
.emit();
}
Expand Down Expand Up @@ -182,29 +182,30 @@ impl<'tcx> InherentCollect<'tcx> {
}

let item = self.tcx.hir().item(id);
let hir::ItemKind::Impl(hir::Impl { of_trait: None, self_ty: ty, items, .. }) = item.kind else {
let impl_span = self.tcx.hir().span(id.hir_id());
let hir::ItemKind::Impl(hir::Impl { of_trait: None, items, .. }) = item.kind else {
return;
};

let self_ty = self.tcx.type_of(item.owner_id);
match *self_ty.kind() {
ty::Adt(def, _) => {
self.check_def_id(item, self_ty, def.did());
self.check_def_id(item, self_ty, def.did(), impl_span);
}
ty::Foreign(did) => {
self.check_def_id(item, self_ty, did);
self.check_def_id(item, self_ty, did, impl_span);
}
ty::Dynamic(data, ..) if data.principal_def_id().is_some() => {
self.check_def_id(item, self_ty, data.principal_def_id().unwrap());
self.check_def_id(item, self_ty, data.principal_def_id().unwrap(), impl_span);
}
ty::Dynamic(..) => {
struct_span_err!(
self.tcx.sess,
ty.span,
impl_span,
E0785,
"cannot define inherent `impl` for a dyn auto trait"
)
.span_label(ty.span, "impl requires at least one non-auto trait")
.span_label(impl_span, "impl requires at least one non-auto trait")
.note("define and implement a new trait or type instead")
.emit();
}
Expand All @@ -221,17 +222,17 @@ impl<'tcx> InherentCollect<'tcx> {
| ty::Never
| ty::FnPtr(_)
| ty::Tuple(..) => {
self.check_primitive_impl(item.owner_id.def_id, self_ty, items, ty.span)
self.check_primitive_impl(item.owner_id.def_id, self_ty, items, impl_span)
}
ty::Alias(..) | ty::Param(_) => {
let mut err = struct_span_err!(
self.tcx.sess,
ty.span,
impl_span,
E0118,
"no nominal type found for inherent implementation"
);

err.span_label(ty.span, "impl requires a nominal type")
err.span_label(impl_span, "impl requires a nominal type")
.note("either implement a trait on it or create a newtype to wrap it instead");

err.emit();
Expand Down
34 changes: 25 additions & 9 deletions compiler/rustc_infer/src/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1783,14 +1783,24 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}))
{
diag.note_expected_found_extra(
&expected_label,
expected,
&found_label,
found,
&sort_string(values.expected, exp_p),
&sort_string(values.found, found_p),
);
if let Some(ExpectedFound { found: found_ty, .. }) = exp_found {
// `Future` is a special opaque type that the compiler
// will try to hide in some case such as `async fn`, so
// to make an error more use friendly we will
// avoid to suggest a mismatch type with a
// type that the user usually are not usign
// directly such as `impl Future<Output = u8>`.
if !self.tcx.ty_is_opaque_future(found_ty) {
diag.note_expected_found_extra(
&expected_label,
expected,
&found_label,
found,
&sort_string(values.expected, exp_p),
&sort_string(values.found, found_p),
);
}
}
}
}
_ => {
Expand Down Expand Up @@ -2854,6 +2864,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
pub enum TyCategory {
Closure,
Opaque,
OpaqueFuture,
Generator(hir::GeneratorKind),
Foreign,
}
Expand All @@ -2863,6 +2874,7 @@ impl TyCategory {
match self {
Self::Closure => "closure",
Self::Opaque => "opaque type",
Self::OpaqueFuture => "future",
Self::Generator(gk) => gk.descr(),
Self::Foreign => "foreign type",
}
Expand All @@ -2871,7 +2883,11 @@ impl TyCategory {
pub fn from_ty(tcx: TyCtxt<'_>, ty: Ty<'_>) -> Option<(Self, DefId)> {
match *ty.kind() {
ty::Closure(def_id, _) => Some((Self::Closure, def_id)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => Some((Self::Opaque, def_id)),
ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
let kind =
if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque };
Some((kind, def_id))
}
ty::Generator(def_id, ..) => {
Some((Self::Generator(tcx.generator_kind(def_id).unwrap()), def_id))
}
Expand Down
31 changes: 13 additions & 18 deletions compiler/rustc_infer/src/infer/error_reporting/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,31 +238,17 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
},
(_, Some(ty)) if self.same_type_modulo_infer(exp_found.expected, ty) => {
diag.span_suggestion_verbose(
exp_span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
self.suggest_await_on_future(diag, exp_span);
diag.span_note(exp_span, "calling an async function returns a future");
}
(Some(ty), _) if self.same_type_modulo_infer(ty, exp_found.found) => match cause.code()
{
ObligationCauseCode::Pattern { span: Some(then_span), .. } => {
diag.span_suggestion_verbose(
then_span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
self.suggest_await_on_future(diag, then_span.shrink_to_hi());
}
ObligationCauseCode::IfExpression(box IfExpressionCause { then_id, .. }) => {
let then_span = self.find_block_span_from_hir_id(*then_id);
diag.span_suggestion_verbose(
then_span.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
self.suggest_await_on_future(diag, then_span.shrink_to_hi());
}
ObligationCauseCode::MatchExpressionArm(box MatchExpressionArmCause {
ref prior_arms,
Expand All @@ -283,6 +269,15 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}

pub fn suggest_await_on_future(&self, diag: &mut Diagnostic, sp: Span) {
diag.span_suggestion_verbose(
sp.shrink_to_hi(),
"consider `await`ing on the `Future`",
".await",
Applicability::MaybeIncorrect,
);
}

pub(super) fn suggest_accessing_field_where_appropriate(
&self,
cause: &ObligationCause<'tcx>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ impl<'tcx> Ty<'tcx> {
ty::Infer(ty::FreshFloatTy(_)) => "fresh floating-point type".into(),
ty::Alias(ty::Projection, _) => "associated type".into(),
ty::Param(p) => format!("type parameter `{p}`").into(),
ty::Alias(ty::Opaque, ..) => "opaque type".into(),
ty::Alias(ty::Opaque, ..) => if tcx.ty_is_opaque_future(self) { "future".into() } else { "opaque type".into() },
ty::Error(_) => "type error".into(),
_ => {
let width = tcx.sess.diagnostic_width();
Expand Down
7 changes: 6 additions & 1 deletion library/std/src/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,12 @@ fn metadata(path: &Path, reparse: ReparsePoint) -> io::Result<FileAttr> {
// If the fallback fails for any reason we return the original error.
match File::open(path, &opts) {
Ok(file) => file.file_attr(),
Err(e) if e.raw_os_error() == Some(c::ERROR_SHARING_VIOLATION as _) => {
Err(e)
if [Some(c::ERROR_SHARING_VIOLATION as _), Some(c::ERROR_ACCESS_DENIED as _)]
.contains(&e.raw_os_error()) =>
{
// `ERROR_ACCESS_DENIED` is returned when the user doesn't have permission for the resource.
// One such example is `System Volume Information` as default but can be created as well
// `ERROR_SHARING_VIOLATION` will almost never be returned.
// Usually if a file is locked you can still read some metadata.
// However, there are special system files, such as
Expand Down
40 changes: 38 additions & 2 deletions src/bootstrap/format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,10 +193,46 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) {
let (tx, rx): (SyncSender<PathBuf>, _) = std::sync::mpsc::sync_channel(128);
let walker = match paths.get(0) {
Some(first) => {
let mut walker = WalkBuilder::new(first);
let find_shortcut_candidates = |p: &PathBuf| {
let mut candidates = Vec::new();
for candidate in WalkBuilder::new(src.clone()).max_depth(Some(3)).build() {
if let Ok(entry) = candidate {
if let Some(dir_name) = p.file_name() {
if entry.path().is_dir() && entry.file_name() == dir_name {
candidates.push(entry.into_path());
}
}
}
}
candidates
};

// Only try to look for shortcut candidates for single component paths like
// `std` and not for e.g. relative paths like `../library/std`.
let should_look_for_shortcut_dir = |p: &PathBuf| p.components().count() == 1;

let mut walker = if should_look_for_shortcut_dir(first) {
if let [single_candidate] = &find_shortcut_candidates(first)[..] {
WalkBuilder::new(single_candidate)
} else {
WalkBuilder::new(first)
}
} else {
WalkBuilder::new(first)
};

for path in &paths[1..] {
walker.add(path);
if should_look_for_shortcut_dir(path) {
if let [single_candidate] = &find_shortcut_candidates(path)[..] {
walker.add(single_candidate);
} else {
walker.add(path);
}
} else {
walker.add(path);
}
}

walker
}
None => WalkBuilder::new(src.clone()),
Expand Down
2 changes: 1 addition & 1 deletion src/doc/book
Submodule book updated 30 files
+2 −2 .github/workflows/main.yml
+1 −0 listings/ch02-guessing-game-tutorial/listing-02-04/output.txt
+2 −2 listings/ch02-guessing-game-tutorial/no-listing-02-without-expect/output.txt
+1 −1 listings/ch03-common-programming-concepts/no-listing-23-statements-dont-return-values/output.txt
+4 −0 listings/ch04-understanding-ownership/no-listing-04-cant-use-after-move/output.txt
+3 −8 listings/ch06-enums-and-pattern-matching/no-listing-07-cant-use-option-directly/output.txt
+4 −0 listings/ch06-enums-and-pattern-matching/no-listing-10-non-exhaustive-match/output.txt
+6 −6 listings/ch07-managing-growing-projects/listing-07-12/output.txt
+0 −1 listings/ch08-common-collections/listing-08-19/output.txt
+1 −1 listings/ch11-writing-automated-tests/listing-11-03/output.txt
+1 −1 listings/ch11-writing-automated-tests/listing-11-10/output.txt
+1 −1 listings/ch11-writing-automated-tests/no-listing-03-introducing-a-bug/output.txt
+1 −1 listings/ch11-writing-automated-tests/no-listing-04-bug-in-add-two/output.txt
+1 −1 listings/ch11-writing-automated-tests/no-listing-06-greeter-with-bug/output.txt
+1 −1 listings/ch11-writing-automated-tests/no-listing-07-custom-failure-message/output.txt
+1 −1 listings/ch11-writing-automated-tests/no-listing-09-guess-with-panic-msg-bug/output.txt
+1 −1 listings/ch11-writing-automated-tests/output-only-01-show-output/output.txt
+2 −2 listings/ch12-an-io-project/listing-12-12/output.txt
+1 −1 listings/ch12-an-io-project/listing-12-16/output.txt
+2 −2 listings/ch13-functional-features/listing-13-14/output.txt
+2 −2 listings/ch15-smart-pointers/listing-15-03/output.txt
+1 −1 listings/ch15-smart-pointers/listing-15-23/output.txt
+3 −0 listings/ch16-fearless-concurrency/listing-16-14/output.txt
+8 −0 listings/ch18-patterns-and-matching/listing-18-08/output.txt
+1 −1 listings/ch18-patterns-and-matching/listing-18-10/output.txt
+2 −2 listings/ch19-advanced-features/listing-19-20/output.txt
+1 −0 listings/ch20-web-server/listing-20-22/output.txt
+1 −0 listings/ch20-web-server/no-listing-04-update-worker-definition/output.txt
+1 −1 rust-toolchain
+1 −1 src/title-page.md
2 changes: 1 addition & 1 deletion src/doc/embedded-book
2 changes: 1 addition & 1 deletion src/doc/nomicon
2 changes: 1 addition & 1 deletion src/doc/reference
3 changes: 1 addition & 2 deletions src/doc/style-guide/src/cargo.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ followed by the `description` at the end of that section.
Don't use quotes around any standard key names; use bare keys. Only use quoted
keys for non-standard keys whose names require them, and avoid introducing such
key names when possible. See the [TOML
specification](https://github.com/toml-lang/toml/blob/master/versions/en/toml-v0.4.0.md#table)
for details.
specification](https://toml.io/en/v1.0.0#keys) for details.

Put a single space both before and after the `=` between a key and value. Do
not indent any key names; start all key names at the start of a line.
Expand Down
1 change: 1 addition & 0 deletions src/librustdoc/formats/item_type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use crate::clean;
/// a heading, edit the listing in `html/render.rs`, function `sidebar_module`. This uses an
/// ordering based on a helper function inside `item_module`, in the same file.
#[derive(Copy, PartialEq, Eq, Hash, Clone, Debug, PartialOrd, Ord)]
#[repr(u8)]
pub(crate) enum ItemType {
Module = 0,
ExternCrate = 1,
Expand Down
11 changes: 10 additions & 1 deletion src/librustdoc/html/render/search_index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,16 @@ pub(crate) fn build_index<'tcx>(
crate_data.serialize_field("doc", &self.doc)?;
crate_data.serialize_field(
"t",
&self.items.iter().map(|item| &item.ty).collect::<Vec<_>>(),
&self
.items
.iter()
.map(|item| {
let n = item.ty as u8;
let c = char::try_from(n + b'A').expect("item types must fit in ASCII");
assert!(c <= 'z', "item types must fit within ASCII printables");
c
})
.collect::<String>(),
)?;
crate_data.serialize_field(
"n",
Expand Down
9 changes: 5 additions & 4 deletions src/librustdoc/html/static/js/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -1939,6 +1939,7 @@ function initSearch(rawSearchIndex) {
* @type {Array<string>}
*/
const searchWords = [];
const charA = "A".charCodeAt(0);
let i, word;
let currentIndex = 0;
let id = 0;
Expand All @@ -1953,7 +1954,7 @@ function initSearch(rawSearchIndex) {
/**
* The raw search data for a given crate. `n`, `t`, `d`, and `q`, `i`, and `f`
* are arrays with the same length. n[i] contains the name of an item.
* t[i] contains the type of that item (as a small integer that represents an
* t[i] contains the type of that item (as a string of characters that represent an
* offset in `itemTypes`). d[i] contains the description of that item.
*
* q[i] contains the full path of the item, or an empty string indicating
Expand All @@ -1980,7 +1981,7 @@ function initSearch(rawSearchIndex) {
* doc: string,
* a: Object,
* n: Array<string>,
* t: Array<Number>,
* t: String,
* d: Array<string>,
* q: Array<string>,
* i: Array<Number>,
Expand Down Expand Up @@ -2009,7 +2010,7 @@ function initSearch(rawSearchIndex) {
searchIndex.push(crateRow);
currentIndex += 1;

// an array of (Number) item types
// a String of one character item type codes
const itemTypes = crateCorpus.t;
// an array of (String) item names
const itemNames = crateCorpus.n;
Expand Down Expand Up @@ -2060,7 +2061,7 @@ function initSearch(rawSearchIndex) {
}
const row = {
crate: crate,
ty: itemTypes[i],
ty: itemTypes.charCodeAt(i) - charA,
name: itemNames[i],
path: itemPaths[i] ? itemPaths[i] : lastPath,
desc: itemDescs[i],
Expand Down
Loading

0 comments on commit 5348a89

Please sign in to comment.