Skip to content

Rollup of 8 pull requests #108015

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 16 commits into from
Feb 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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