Skip to content

Commit

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

Successful merges:

 - #108726 (tidy: enforce comment blocks to have an even number of backticks)
 - #108797 (Allow binary files to go through the `FileLoader`)
 - #108841 (Add suggestion to diagnostic when user has array but trait wants slice. (rebased))
 - #108984 (bootstrap: document tidy)
 - #109013 (Give proper error message when tcx wasn't passed to decoder)
 - #109017 (remove duplicated calls to sort_string)
 - #109018 (Expand on the allocator comment in `rustc-main`)
 - #109028 (Add eslint checks for rustdoc-js tester)
 - #109034 (Commit some tests for the new solver + lazy norm)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Mar 12, 2023
2 parents 150cb38 + 3166b4a commit 24c0b81
Show file tree
Hide file tree
Showing 39 changed files with 914 additions and 87 deletions.
9 changes: 9 additions & 0 deletions compiler/rustc/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,15 @@
// The two crates we link to here, `std` and `rustc_driver`, are both dynamic
// libraries. So we must reference jemalloc symbols one way or another, because
// this file is the only object code in the rustc executable.
//
// NOTE: if you are reading this comment because you want to set a custom `global_allocator` for
// benchmarking, consider using the benchmarks in the `rustc-perf` collector suite instead:
// https://github.com/rust-lang/rustc-perf/blob/master/collector/README.md#profiling
//
// NOTE: if you are reading this comment because you want to replace jemalloc with another allocator
// to compare their performance, see
// https://github.com/rust-lang/rust/commit/b90cfc887c31c3e7a9e6d462e2464db1fe506175#diff-43914724af6e464c1da2171e4a9b6c7e607d5bc1203fa95c0ab85be4122605ef
// for an example of how to do so.

#[unix_sigpipe = "sig_dfl"]
fn main() {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1052,6 +1052,7 @@ impl<'a> MethodDef<'a> {
/// ::core::hash::Hash::hash(&{ self.y }, state)
/// }
/// }
/// ```
fn expand_struct_method_body<'b>(
&self,
cx: &mut ExtCtxt<'_>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,7 @@ fn build_enum_variant_member_di_node<'ll, 'tcx>(
/// DW_TAG_structure_type (type of variant 1)
/// DW_TAG_structure_type (type of variant 2)
/// DW_TAG_structure_type (type of variant 3)
/// ```
struct VariantMemberInfo<'a, 'll> {
variant_index: VariantIdx,
variant_name: Cow<'a, str>,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_error_codes/src/error_codes/E0368.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl Add for Foo {
fn main() {
let mut x: Foo = Foo(5);
x += Foo(7); // error, `+= cannot be applied to the type `Foo`
x += Foo(7); // error, `+=` cannot be applied to the type `Foo`
}
```

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_error_codes/src/error_codes/E0710.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ An unknown tool name was found in a scoped lint.
Erroneous code examples:

```compile_fail,E0710
#[allow(clipp::filter_map)] // error!`
#[allow(clipp::filter_map)] // error!
fn main() {
// business logic
}
```

```compile_fail,E0710
#[warn(clipp::filter_map)] // error!`
#[warn(clipp::filter_map)] // error!
fn main() {
// business logic
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
///
/// Here:
/// - E would be `fn(&u32) -> &u32`.
/// - S would be `fn(&u32) ->
/// - S would be `fn(&u32) -> ?T`
/// - E' is `&'!0 u32 -> &'!0 u32`
/// - S' is `&'?0 u32 -> ?T`
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let (mention_influencer, influencer_point) =
if sup_origin.span().overlaps(param.param_ty_span) {
// Account for `async fn` like in `async-await/issues/issue-62097.rs`.
// The desugaring of `async `fn`s causes `sup_origin` and `param` to point at the same
// The desugaring of `async fn`s causes `sup_origin` and `param` to point at the same
// place (but with different `ctxt`, hence `overlaps` instead of `==` above).
//
// This avoids the following:
Expand Down
23 changes: 18 additions & 5 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -311,8 +311,11 @@ impl<T: ParameterizedOverTcx> LazyArray<T> {
impl<'a, 'tcx> DecodeContext<'a, 'tcx> {
#[inline]
fn tcx(&self) -> TyCtxt<'tcx> {
debug_assert!(self.tcx.is_some(), "missing TyCtxt in DecodeContext");
self.tcx.unwrap()
let Some(tcx) = self.tcx else {
bug!("No TyCtxt found for decoding. \
You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.");
};
tcx
}

#[inline]
Expand Down Expand Up @@ -454,7 +457,12 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ast::AttrId {
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> SyntaxContext {
let cdata = decoder.cdata();
let sess = decoder.sess.unwrap();

let Some(sess) = decoder.sess else {
bug!("Cannot decode SyntaxContext without Session.\
You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.");
};

let cname = cdata.root.name;
rustc_span::hygiene::decode_syntax_context(decoder, &cdata.hygiene_context, |_, id| {
debug!("SpecializedDecoder<SyntaxContext>: decoding {}", id);
Expand All @@ -471,7 +479,11 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for SyntaxContext {
impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for ExpnId {
fn decode(decoder: &mut DecodeContext<'a, 'tcx>) -> ExpnId {
let local_cdata = decoder.cdata();
let sess = decoder.sess.unwrap();

let Some(sess) = decoder.sess else {
bug!("Cannot decode ExpnId without Session. \
You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.");
};

let cnum = CrateNum::decode(decoder);
let index = u32::decode(decoder);
Expand Down Expand Up @@ -520,7 +532,8 @@ impl<'a, 'tcx> Decodable<DecodeContext<'a, 'tcx>> for Span {
let hi = lo + len;

let Some(sess) = decoder.sess else {
bug!("Cannot decode Span without Session.")
bug!("Cannot decode Span without Session. \
You need to explicitly pass `(crate_metadata_ref, tcx)` to `decode` instead of just `crate_metadata_ref`.")
};

// Index of the file in the corresponding crate's list of encoded files.
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_middle/src/mir/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ fn dump_matched_mir_node<'tcx, F>(
// see notes on #41697 above
let def_path =
ty::print::with_forced_impl_filename_line!(tcx.def_path_str(body.source.def_id()));
// ignore-tidy-odd-backticks the literal below is fine
write!(file, "// MIR for `{}", def_path)?;
match body.source.promoted {
None => write!(file, "`")?,
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_middle/src/ty/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,8 @@ impl<'tcx> TypeError<'tcx> {
.into(),
RegionsPlaceholderMismatch => "one type is more general than the other".into(),
ArgumentSorts(values, _) | Sorts(values) => {
let mut expected = values.expected.sort_string(tcx);
let mut found = values.found.sort_string(tcx);
if expected == found {
expected = values.expected.sort_string(tcx);
found = values.found.sort_string(tcx);
}
let expected = values.expected.sort_string(tcx);
let found = values.found.sort_string(tcx);
report_maybe_different(&expected, &found).into()
}
Traits(values) => {
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_mir_build/src/build/matches/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
// let place = Foo::new();
// match place { Foo { .. } if { let tmp1 = &place; inspect(*tmp1) }
// => { let tmp2 = place; feed(tmp2) }, ... }
// ```
//
// And an input like:
//
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ pub trait FileLoader {

/// Read the contents of a UTF-8 file into memory.
fn read_file(&self, path: &Path) -> io::Result<String>;

/// Read the contents of a potentially non-UTF-8 file into memory.
fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>>;
}

/// A FileLoader that uses std::fs to load real files.
Expand All @@ -113,6 +116,10 @@ impl FileLoader for RealFileLoader {
fn read_file(&self, path: &Path) -> io::Result<String> {
fs::read_to_string(path)
}

fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> {
fs::read(path)
}
}

/// This is a [SourceFile] identifier that is used to correlate source files between
Expand Down Expand Up @@ -220,9 +227,7 @@ impl SourceMap {
/// Unlike `load_file`, guarantees that no normalization like BOM-removal
/// takes place.
pub fn load_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> {
// Ideally, this should use `self.file_loader`, but it can't
// deal with binary files yet.
let bytes = fs::read(path)?;
let bytes = self.file_loader.read_binary_file(path)?;

// We need to add file to the `SourceMap`, so that it is present
// in dep-info. There's also an edge case that file might be both
Expand Down
3 changes: 2 additions & 1 deletion compiler/rustc_trait_selection/src/solve/assembly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
///
/// To deal with this, we first try to normalize the self type and add the candidates for the normalized
/// self type to the list of candidates in case that succeeds. Note that we can't just eagerly return in
/// this case as projections as self types add `
/// this case as projections as self types add
// FIXME complete the unfinished sentence above
fn assemble_candidates_after_normalizing_self_ty<G: GoalKind<'tcx>>(
&mut self,
goal: Goal<'tcx, G>,
Expand Down
20 changes: 14 additions & 6 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1024,7 +1024,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Can't show anything else useful, try to find similar impls.
let impl_candidates = self.find_similar_impl_candidates(trait_predicate);
if !self.report_similar_impl_candidates(
impl_candidates,
&impl_candidates,
trait_ref,
body_def_id,
&mut err,
Expand Down Expand Up @@ -1060,14 +1060,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let impl_candidates =
self.find_similar_impl_candidates(trait_pred);
self.report_similar_impl_candidates(
impl_candidates,
&impl_candidates,
trait_ref,
body_def_id,
&mut err,
true,
);
}
}

self.maybe_suggest_convert_to_slice(
&mut err,
trait_ref,
impl_candidates.as_slice(),
span,
);
}

// Changing mutability doesn't make a difference to whether we have
Expand Down Expand Up @@ -1514,7 +1521,7 @@ trait InferCtxtPrivExt<'tcx> {

fn report_similar_impl_candidates(
&self,
impl_candidates: Vec<ImplCandidate<'tcx>>,
impl_candidates: &[ImplCandidate<'tcx>],
trait_ref: ty::PolyTraitRef<'tcx>,
body_def_id: LocalDefId,
err: &mut Diagnostic,
Expand Down Expand Up @@ -2004,7 +2011,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {

fn report_similar_impl_candidates(
&self,
impl_candidates: Vec<ImplCandidate<'tcx>>,
impl_candidates: &[ImplCandidate<'tcx>],
trait_ref: ty::PolyTraitRef<'tcx>,
body_def_id: LocalDefId,
err: &mut Diagnostic,
Expand Down Expand Up @@ -2113,7 +2120,8 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// Prefer more similar candidates first, then sort lexicographically
// by their normalized string representation.
let mut normalized_impl_candidates_and_similarities = impl_candidates
.into_iter()
.iter()
.copied()
.map(|ImplCandidate { trait_ref, similarity }| {
// FIXME(compiler-errors): This should be using `NormalizeExt::normalize`
let normalized = self
Expand Down Expand Up @@ -2326,7 +2334,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
if impl_candidates.len() < 10 {
self.report_similar_impl_candidates(
impl_candidates,
impl_candidates.as_slice(),
trait_ref,
obligation.cause.body_id,
&mut err,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ignore-tidy-filelength

use super::{
DefIdOrName, FindExprBySpan, Obligation, ObligationCause, ObligationCauseCode,
DefIdOrName, FindExprBySpan, ImplCandidate, Obligation, ObligationCause, ObligationCauseCode,
PredicateObligation,
};

Expand Down Expand Up @@ -382,6 +382,14 @@ pub trait TypeErrCtxtExt<'tcx> {
body_id: hir::HirId,
param_env: ty::ParamEnv<'tcx>,
) -> Vec<Option<(Span, (DefId, Ty<'tcx>))>>;

fn maybe_suggest_convert_to_slice(
&self,
err: &mut Diagnostic,
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
candidate_impls: &[ImplCandidate<'tcx>],
span: Span,
);
}

fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -> (Span, String) {
Expand Down Expand Up @@ -2220,7 +2228,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// - `BuiltinDerivedObligation` with a generator witness (A)
// - `BuiltinDerivedObligation` with a generator (A)
// - `BuiltinDerivedObligation` with `impl std::future::Future` (A)
// - `BindingObligation` with `impl_send (Send requirement)
// - `BindingObligation` with `impl_send` (Send requirement)
//
// The first obligation in the chain is the most useful and has the generator that captured
// the type. The last generator (`outer_generator` below) has information about where the
Expand Down Expand Up @@ -3826,6 +3834,73 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
assocs_in_this_method
}

/// If the type that failed selection is an array or a reference to an array,
/// but the trait is implemented for slices, suggest that the user converts
/// the array into a slice.
fn maybe_suggest_convert_to_slice(
&self,
err: &mut Diagnostic,
trait_ref: ty::Binder<'tcx, ty::TraitRef<'tcx>>,
candidate_impls: &[ImplCandidate<'tcx>],
span: Span,
) {
// Three cases where we can make a suggestion:
// 1. `[T; _]` (array of T)
// 2. `&[T; _]` (reference to array of T)
// 3. `&mut [T; _]` (mutable reference to array of T)
let (element_ty, mut mutability) = match *trait_ref.skip_binder().self_ty().kind() {
ty::Array(element_ty, _) => (element_ty, None),

ty::Ref(_, pointee_ty, mutability) => match *pointee_ty.kind() {
ty::Array(element_ty, _) => (element_ty, Some(mutability)),
_ => return,
},

_ => return,
};

// Go through all the candidate impls to see if any of them is for
// slices of `element_ty` with `mutability`.
let mut is_slice = |candidate: Ty<'tcx>| match *candidate.kind() {
ty::RawPtr(ty::TypeAndMut { ty: t, mutbl: m }) | ty::Ref(_, t, m) => {
if matches!(*t.kind(), ty::Slice(e) if e == element_ty)
&& m == mutability.unwrap_or(m)
{
// Use the candidate's mutability going forward.
mutability = Some(m);
true
} else {
false
}
}
_ => false,
};

// Grab the first candidate that matches, if any, and make a suggestion.
if let Some(slice_ty) = candidate_impls
.iter()
.map(|trait_ref| trait_ref.trait_ref.self_ty())
.filter(|t| is_slice(*t))
.next()
{
let msg = &format!("convert the array to a `{}` slice instead", slice_ty);

if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
let mut suggestions = vec![];
if snippet.starts_with('&') {
} else if let Some(hir::Mutability::Mut) = mutability {
suggestions.push((span.shrink_to_lo(), "&mut ".into()));
} else {
suggestions.push((span.shrink_to_lo(), "&".into()));
}
suggestions.push((span.shrink_to_hi(), "[..]".into()));
err.multipart_suggestion_verbose(msg, suggestions, Applicability::MaybeIncorrect);
} else {
err.span_help(span, msg);
}
}
}
}

/// Add a hint to add a missing borrow or remove an unnecessary one.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_type_ir/src/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
//! It defines a "skeleton" of how they should be folded.
//! - `TypeSuperFoldable`. This is implemented only for each type of interest,
//! and defines the folding "skeleton" for these types.
//! - `TypeFolder`/`FallibleTypeFolder. One of these is implemented for each
//! - `TypeFolder`/`FallibleTypeFolder`. One of these is implemented for each
//! folder. This defines how types of interest are folded.
//!
//! This means each fold is a mixture of (a) generic folding operations, and (b)
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -741,6 +741,7 @@ impl<'a> Builder<'a> {
doc::EmbeddedBook,
doc::EditionGuide,
doc::StyleGuide,
doc::Tidy,
),
Kind::Dist => describe!(
dist::Docs,
Expand Down
Loading

0 comments on commit 24c0b81

Please sign in to comment.