Skip to content

Rollup of 8 pull requests #95666

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

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
76756cc
bootstrap.py: nixos check in /etc/os-release with quotes
ben0x539 Mar 23, 2022
064a559
Fix `x doc --stage 0 compiler`
jyn514 Mar 29, 2022
bf2c3b0
Fix ICE in rustdoc intra doc links when trying to get traits in scope…
GuillaumeGomez Apr 4, 2022
50cc0fa
Add test to ensure rustdoc does not panic on intra doc link pass
GuillaumeGomez Apr 4, 2022
6ece80f
diagnostics: use correct span for const generics
notriddle Apr 4, 2022
92246c0
Rely on #[link] attribute for unwind on Fuchsia.
anp Apr 4, 2022
ccb704c
Update panic docs to make it clearer when to use panic vs Result
yaahc Apr 4, 2022
0d2a000
Suggest derivable trait on E0277
ohno418 Mar 31, 2022
0ff2f58
Suggest only when Rhs for PartialEq and PartialOrd is the same type a…
ohno418 Apr 1, 2022
a8877cf
Handle reporting invariance of fn pointer
compiler-errors Apr 2, 2022
de23782
Suggest only when all fields impl the trait
ohno418 Apr 3, 2022
2a129d4
Format invariance notes with backticks
compiler-errors Apr 2, 2022
c5c66a6
Rollup merge of #95234 - ben0x539:nixquotes, r=Dylan-DPC
Dylan-DPC Apr 5, 2022
27fb711
Rollup merge of #95449 - jyn514:doc-stage-0, r=ehuss
Dylan-DPC Apr 5, 2022
c95357a
Rollup merge of #95525 - ohno418:suggest-derivable-trait-E0277, r=com…
Dylan-DPC Apr 5, 2022
78395bb
Rollup merge of #95607 - compiler-errors:issue-95272, r=Aaron1011
Dylan-DPC Apr 5, 2022
bec8741
Rollup merge of #95645 - GuillaumeGomez:intra-doc-link-ice-traits-in-…
Dylan-DPC Apr 5, 2022
6d09ee0
Rollup merge of #95654 - notriddle:notriddle/issue-95616, r=davidtwco
Dylan-DPC Apr 5, 2022
1aa4d58
Rollup merge of #95659 - anp:remove-link-print, r=tmandry
Dylan-DPC Apr 5, 2022
87836c5
Rollup merge of #95660 - yaahc:panic-docs-update, r=Dylan-DPC
Dylan-DPC Apr 5, 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
2 changes: 1 addition & 1 deletion compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2068,7 +2068,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
hir::GenericParam {
hir_id,
name,
span: self.lower_span(param.ident.span),
span: self.lower_span(param.span()),
pure_wrt_drop: self.sess.contains_name(&param.attrs, sym::may_dangle),
bounds: self.arena.alloc_from_iter(bounds),
kind,
Expand Down
19 changes: 15 additions & 4 deletions compiler/rustc_borrowck/src/diagnostics/region_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -330,14 +330,14 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
ty::RawPtr(ty_mut) => {
assert_eq!(ty_mut.mutbl, rustc_hir::Mutability::Mut);
(
format!("a mutable pointer to {}", ty_mut.ty),
format!("a mutable pointer to `{}`", ty_mut.ty),
"mutable pointers are invariant over their type parameter".to_string(),
)
}
ty::Ref(_, inner_ty, mutbl) => {
assert_eq!(*mutbl, rustc_hir::Mutability::Mut);
(
format!("a mutable reference to {}", inner_ty),
format!("a mutable reference to `{}`", inner_ty),
"mutable references are invariant over their type parameter"
.to_string(),
)
Expand All @@ -351,10 +351,21 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let adt_desc = adt.descr();

let desc = format!(
"the type {ty}, which makes the generic argument {generic_arg} invariant"
"the type `{ty}`, which makes the generic argument `{generic_arg}` invariant"
);
let note = format!(
"the {adt_desc} {base_ty} is invariant over the parameter {base_generic_arg}"
"the {adt_desc} `{base_ty}` is invariant over the parameter `{base_generic_arg}`"
);
(desc, note)
}
ty::FnDef(def_id, _) => {
let name = self.infcx.tcx.item_name(*def_id);
let identity_substs =
InternalSubsts::identity_for_item(self.infcx.tcx, *def_id);
let desc = format!("a function pointer to `{name}`");
let note = format!(
"the function `{name}` is invariant over the parameter `{}`",
identity_substs[param_index as usize]
);
(desc, note)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
);
self.note_version_mismatch(&mut err, &trait_ref);
self.suggest_remove_await(&obligation, &mut err);
self.suggest_derive(&obligation, &mut err, trait_predicate);

if Some(trait_ref.def_id()) == tcx.lang_items().try_trait() {
self.suggest_await_before_try(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@ pub trait InferCtxtExt<'tcx> {
err: &mut Diagnostic,
trait_ref: &ty::PolyTraitRef<'tcx>,
);

fn suggest_derive(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
);
}

fn predicate_constraint(generics: &hir::Generics<'_>, pred: String) -> (Span, String) {
Expand Down Expand Up @@ -2650,6 +2657,68 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
_ => {}
}
}

fn suggest_derive(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) {
let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
return;
};
let (adt, substs) = match trait_pred.skip_binder().self_ty().kind() {
ty::Adt(adt, substs) if adt.did().is_local() => (adt, substs),
_ => return,
};
let can_derive = {
let is_derivable_trait = match diagnostic_name {
sym::Default => !adt.is_enum(),
sym::PartialEq | sym::PartialOrd => {
let rhs_ty = trait_pred.skip_binder().trait_ref.substs.type_at(1);
trait_pred.skip_binder().self_ty() == rhs_ty
}
sym::Eq | sym::Ord | sym::Clone | sym::Copy | sym::Hash | sym::Debug => true,
_ => false,
};
is_derivable_trait &&
// Ensure all fields impl the trait.
adt.all_fields().all(|field| {
let field_ty = field.ty(self.tcx, substs);
let trait_substs = match diagnostic_name {
sym::PartialEq | sym::PartialOrd => {
self.tcx.mk_substs_trait(field_ty, &[field_ty.into()])
}
_ => self.tcx.mk_substs_trait(field_ty, &[]),
};
let trait_pred = trait_pred.map_bound_ref(|tr| ty::TraitPredicate {
trait_ref: ty::TraitRef {
substs: trait_substs,
..trait_pred.skip_binder().trait_ref
},
..*tr
});
let field_obl = Obligation::new(
obligation.cause.clone(),
obligation.param_env,
trait_pred.to_predicate(self.tcx),
);
self.predicate_must_hold_modulo_regions(&field_obl)
})
};
if can_derive {
err.span_suggestion_verbose(
self.tcx.def_span(adt.did()).shrink_to_lo(),
&format!(
"consider annotating `{}` with `#[derive({})]`",
trait_pred.skip_binder().self_ty(),
diagnostic_name.to_string(),
),
format!("#[derive({})]\n", diagnostic_name.to_string()),
Applicability::MaybeIncorrect,
);
}
}
}

/// Collect all the returned expressions within the input expression.
Expand Down
26 changes: 19 additions & 7 deletions library/core/src/macros/panic.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
Panics the current thread.

This allows a program to terminate immediately and provide feedback
to the caller of the program. `panic!` should be used when a program reaches
an unrecoverable state.
to the caller of the program.

This macro is the perfect way to assert conditions in example code and in
tests. `panic!` is closely tied with the `unwrap` method of both
Expand All @@ -21,13 +20,25 @@ Inside the hook a panic can be accessed as a `&dyn Any + Send`,
which contains either a `&str` or `String` for regular `panic!()` invocations.
To panic with a value of another other type, [`panic_any`] can be used.

[`Result`] enum is often a better solution for recovering from errors than
using the `panic!` macro. This macro should be used to avoid proceeding using
incorrect values, such as from external sources. Detailed information about
error handling is found in the [book].

See also the macro [`compile_error!`], for raising errors during compilation.

# When to use `panic!` vs `Result`

The Rust model of error handling groups errors into two major categories:
recoverable and unrecoverable errors. For a recoverable error, such as a file
not found error, it’s reasonable to report the problem to the user and retry
the operation. Unrecoverable errors are always symptoms of bugs, like trying to
access a location beyond the end of an array.

The Rust language and standard library provides `Result` and `panic!` as parts
of two complementary systems for representing, reporting, propagating, reacting
to, and discarding errors for in these two categories.

The `panic!` macro is provided to represent unrecoverable errors, whereas the
`Result` enum is provided to represent recoverable errors. For more detailed
information about error handling check out the [book] or the [`std::result`]
module docs.

[ounwrap]: Option::unwrap
[runwrap]: Result::unwrap
[`std::panic::set_hook()`]: ../std/panic/fn.set_hook.html
Expand All @@ -36,6 +47,7 @@ See also the macro [`compile_error!`], for raising errors during compilation.
[`Any`]: crate::any::Any
[`format!`]: ../std/macro.format.html
[book]: ../book/ch09-00-error-handling.html
[`std::result`]: ../std/result/index.html

# Current implementation

Expand Down
2 changes: 0 additions & 2 deletions library/unwind/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ fn main() {
// This is handled in the target spec with late_link_args_[static|dynamic]
} else if target.contains("uwp-windows-gnu") {
println!("cargo:rustc-link-lib=unwind");
} else if target.contains("fuchsia") {
println!("cargo:rustc-link-lib=unwind");
} else if target.contains("haiku") {
println!("cargo:rustc-link-lib=gcc_s");
} else if target.contains("redox") {
Expand Down
20 changes: 16 additions & 4 deletions src/bootstrap/bin/rustdoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ fn main() {
let libdir = env::var_os("RUSTDOC_LIBDIR").expect("RUSTDOC_LIBDIR was not set");
let sysroot = env::var_os("RUSTC_SYSROOT").expect("RUSTC_SYSROOT was not set");

// Detect whether or not we're a build script depending on whether --target
// is passed (a bit janky...)
let target = args.windows(2).find(|w| &*w[0] == "--target").and_then(|w| w[1].to_str());

use std::str::FromStr;

let verbose = match env::var("RUSTC_VERBOSE") {
Expand All @@ -26,10 +30,18 @@ fn main() {
dylib_path.insert(0, PathBuf::from(libdir.clone()));

let mut cmd = Command::new(rustdoc);
cmd.args(&args)
.arg("--sysroot")
.arg(&sysroot)
.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());

if target.is_some() {
// The stage0 compiler has a special sysroot distinct from what we
// actually downloaded, so we just always pass the `--sysroot` option,
// unless one is already set.
if !args.iter().any(|arg| arg == "--sysroot") {
cmd.arg("--sysroot").arg(&sysroot);
}
}

cmd.args(&args);
cmd.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());

// Force all crates compiled by this compiler to (a) be unstable and (b)
// allow the `rustc_private` feature to link to other unstable crates
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ def fix_bin_or_dylib(self, fname):
# The latter one does not exist on NixOS when using tmpfs as root.
try:
with open("/etc/os-release", "r") as f:
if not any(line.strip() == "ID=nixos" for line in f):
if not any(l.strip() in ["ID=nixos", "ID='nixos'", 'ID="nixos"'] for l in f):
return
except FileNotFoundError:
return
Expand Down
8 changes: 7 additions & 1 deletion src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,7 @@ fn main_options(options: config::Options) -> MainResult {
let externs = options.externs.clone();
let render_options = options.render_options.clone();
let scrape_examples_options = options.scrape_examples_options.clone();
let document_private = options.render_options.document_private;
let config = core::create_config(options);

interface::create_compiler_and_run(config, |compiler| {
Expand All @@ -791,7 +792,12 @@ fn main_options(options: config::Options) -> MainResult {
let (resolver, resolver_caches) = {
let (krate, resolver, _) = &*abort_on_err(queries.expansion(), sess).peek();
let resolver_caches = resolver.borrow_mut().access(|resolver| {
collect_intra_doc_links::early_resolve_intra_doc_links(resolver, krate, externs)
collect_intra_doc_links::early_resolve_intra_doc_links(
resolver,
krate,
externs,
document_private,
)
});
(resolver.clone(), resolver_caches)
};
Expand Down
5 changes: 4 additions & 1 deletion src/librustdoc/passes/collect_intra_doc_links/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ crate fn early_resolve_intra_doc_links(
resolver: &mut Resolver<'_>,
krate: &ast::Crate,
externs: Externs,
document_private_items: bool,
) -> ResolverCaches {
let mut loader = IntraLinkCrateLoader {
resolver,
Expand All @@ -30,6 +31,7 @@ crate fn early_resolve_intra_doc_links(
traits_in_scope: Default::default(),
all_traits: Default::default(),
all_trait_impls: Default::default(),
document_private_items,
};

// Because of the `crate::` prefix, any doc comment can reference
Expand Down Expand Up @@ -66,6 +68,7 @@ struct IntraLinkCrateLoader<'r, 'ra> {
traits_in_scope: DefIdMap<Vec<TraitCandidate>>,
all_traits: Vec<DefId>,
all_trait_impls: Vec<DefId>,
document_private_items: bool,
}

impl IntraLinkCrateLoader<'_, '_> {
Expand Down Expand Up @@ -175,7 +178,7 @@ impl IntraLinkCrateLoader<'_, '_> {
}

for child in self.resolver.module_children_or_reexports(module_id) {
if child.vis == Visibility::Public {
if child.vis == Visibility::Public || self.document_private_items {
if let Some(def_id) = child.res.opt_def_id() {
self.add_traits_in_parent_scope(def_id);
}
Expand Down
7 changes: 7 additions & 0 deletions src/test/rustdoc/issue-95633.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// compile-flags: --document-private-items

// This ensures that no ICE is triggered when rustdoc is run on this code.

mod stdlib {
pub (crate) use std::i8;
}
8 changes: 8 additions & 0 deletions src/test/ui/array-slice-vec/repeat_empty_ok.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ LL | let headers = [Header{value: &[]}; 128];
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
= note: the `Copy` trait is required because the repeated element will be copied
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
|
LL | #[derive(Copy)]
|

error[E0277]: the trait bound `Header<'_>: Copy` is not satisfied
--> $DIR/repeat_empty_ok.rs:13:19
Expand All @@ -13,6 +17,10 @@ LL | let headers = [Header{value: &[0]}; 128];
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Copy` is not implemented for `Header<'_>`
|
= note: the `Copy` trait is required because the repeated element will be copied
help: consider annotating `Header<'_>` with `#[derive(Copy)]`
|
LL | #[derive(Copy)]
|

error: aborting due to 2 previous errors

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ LL | (a, b)
| ^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
= note: the struct Type<'a> is invariant over the parameter 'a
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: lifetime may not live long enough
Expand All @@ -26,8 +26,8 @@ LL | (a, b)
| ^^^^^^ function was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
= note: the struct Type<'a> is invariant over the parameter 'a
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

help: `'a` and `'b` must be the same: replace one with the other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ LL | let a = bar(f, x);
| ^^^^^^^^^ argument requires that `'a` must outlive `'b`
|
= help: consider adding the following bound: `'a: 'b`
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
= note: the struct Type<'a> is invariant over the parameter 'a
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: lifetime may not live long enough
Expand All @@ -26,8 +26,8 @@ LL | let b = bar(f, y);
| ^^^^^^^^^ argument requires that `'b` must outlive `'a`
|
= help: consider adding the following bound: `'b: 'a`
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
= note: the struct Type<'a> is invariant over the parameter 'a
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

help: `'a` and `'b` must be the same: replace one with the other
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ LL | fn baz<'a, 'b>(x: Type<'a>) -> Type<'static> {
LL | bar(foo, x)
| ^^^^^^^^^^^ returning this value requires that `'a` must outlive `'static`
|
= note: requirement occurs because of the type Type<'_>, which makes the generic argument '_ invariant
= note: the struct Type<'a> is invariant over the parameter 'a
= note: requirement occurs because of the type `Type<'_>`, which makes the generic argument `'_` invariant
= note: the struct `Type<'a>` is invariant over the parameter `'a`
= help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance

error: aborting due to previous error
Expand Down
Loading