Skip to content

Commit

Permalink
Auto merge of rust-lang#107919 - Dylan-DPC:rollup-fkl9swa, r=Dylan-DPC
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - rust-lang#105019 (Add parentheses properly for borrowing suggestion)
 - rust-lang#106001 (Stop at the first `NULL` argument when iterating `argv`)
 - rust-lang#107098 (Suggest function call on pattern type mismatch)
 - rust-lang#107490 (rustdoc: remove inconsistently-present sidebar tooltips)
 - rust-lang#107855 (Add a couple random projection tests for new solver)
 - rust-lang#107857 (Add ui test for implementation on projection)
 - rust-lang#107878 (Clarify `new_size` for realloc means bytes)
 - rust-lang#107888 (revert rust-lang#107074, add regression test)
 - rust-lang#107900 (Zero the `REPARSE_MOUNTPOINT_DATA_BUFFER` header)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Feb 11, 2023
2 parents 1623ab0 + a50c379 commit 71f6675
Show file tree
Hide file tree
Showing 25 changed files with 320 additions and 70 deletions.
11 changes: 10 additions & 1 deletion compiler/rustc_const_eval/src/transform/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use rustc_middle::mir::{
RetagKind, RuntimePhase, Rvalue, SourceScope, Statement, StatementKind, Terminator,
TerminatorKind, UnOp, START_BLOCK,
};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt};
use rustc_middle::ty::{self, InstanceDef, ParamEnv, Ty, TyCtxt, TypeVisitable};
use rustc_mir_dataflow::impls::MaybeStorageLive;
use rustc_mir_dataflow::storage::always_storage_live_locals;
use rustc_mir_dataflow::{Analysis, ResultsCursor};
Expand Down Expand Up @@ -231,6 +231,15 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
return true;
}

// We sometimes have to use `defining_opaque_types` for subtyping
// to succeed here and figuring out how exactly that should work
// is annoying. It is harmless enough to just not validate anything
// in that case. We still check this after analysis as all opque
// types have been revealed at this point.
if (src, dest).has_opaque_types() {
return true;
}

crate::util::is_subtype(self.tcx, self.param_env, src, dest)
}
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/_match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// #55810: Type check patterns first so we get types for all bindings.
let scrut_span = scrut.span.find_ancestor_inside(expr.span).unwrap_or(scrut.span);
for arm in arms {
self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), true);
self.check_pat_top(&arm.pat, scrutinee_ty, Some(scrut_span), Some(scrut));
}

// Now typecheck the blocks.
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_hir_typeck/src/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ pub(super) fn check_fn<'a, 'tcx>(
for (idx, (param_ty, param)) in inputs_fn.chain(maybe_va_list).zip(body.params).enumerate() {
// Check the pattern.
let ty_span = try { inputs_hir?.get(idx)?.span };
fcx.check_pat_top(&param.pat, param_ty, ty_span, false);
fcx.check_pat_top(&param.pat, param_ty, ty_span, None);

// Check that argument is Sized.
// The check for a non-trivial pattern is a hack to avoid duplicate warnings
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1330,11 +1330,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {

// Does the expected pattern type originate from an expression and what is the span?
let (origin_expr, ty_span) = match (decl.ty, decl.init) {
(Some(ty), _) => (false, Some(ty.span)), // Bias towards the explicit user type.
(Some(ty), _) => (None, Some(ty.span)), // Bias towards the explicit user type.
(_, Some(init)) => {
(true, Some(init.span.find_ancestor_inside(decl.span).unwrap_or(init.span)))
(Some(init), Some(init.span.find_ancestor_inside(decl.span).unwrap_or(init.span)))
} // No explicit type; so use the scrutinee.
_ => (false, None), // We have `let $pat;`, so the expected type is unconstrained.
_ => (None, None), // We have `let $pat;`, so the expected type is unconstrained.
};

// Type check the pattern. Override if necessary to avoid knock-on errors.
Expand Down
19 changes: 14 additions & 5 deletions compiler/rustc_hir_typeck/src/pat.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ struct TopInfo<'tcx> {
/// Was the origin of the `span` from a scrutinee expression?
///
/// Otherwise there is no scrutinee and it could be e.g. from the type of a formal parameter.
origin_expr: bool,
origin_expr: Option<&'tcx hir::Expr<'tcx>>,
/// The span giving rise to the `expected` type, if one could be provided.
///
/// If `origin_expr` is `true`, then this is the span of the scrutinee as in:
Expand Down Expand Up @@ -74,7 +74,8 @@ struct TopInfo<'tcx> {

impl<'tcx> FnCtxt<'_, 'tcx> {
fn pattern_cause(&self, ti: TopInfo<'tcx>, cause_span: Span) -> ObligationCause<'tcx> {
let code = Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr };
let code =
Pattern { span: ti.span, root_ty: ti.expected, origin_expr: ti.origin_expr.is_some() };
self.cause(cause_span, code)
}

Expand All @@ -85,7 +86,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
actual: Ty<'tcx>,
ti: TopInfo<'tcx>,
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)
let mut diag =
self.demand_eqtype_with_origin(&self.pattern_cause(ti, cause_span), expected, actual)?;
if let Some(expr) = ti.origin_expr {
self.suggest_fn_call(&mut diag, expr, expected, |output| {
self.can_eq(self.param_env, output, actual).is_ok()
});
}
Some(diag)
}

fn demand_eqtype_pat(
Expand Down Expand Up @@ -127,7 +135,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pat: &'tcx Pat<'tcx>,
expected: Ty<'tcx>,
span: Option<Span>,
origin_expr: bool,
origin_expr: Option<&'tcx hir::Expr<'tcx>>,
) {
let info = TopInfo { expected, origin_expr, span };
self.check_pat(pat, expected, INITIAL_BM, info);
Expand Down Expand Up @@ -2146,7 +2154,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.help("the semantics of slice patterns changed recently; see issue #62254");
} else if self.autoderef(span, expected_ty)
.any(|(ty, _)| matches!(ty.kind(), ty::Slice(..) | ty::Array(..)))
&& let (Some(span), true) = (ti.span, ti.origin_expr)
&& let Some(span) = ti.span
&& let Some(_) = ti.origin_expr
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
{
let ty = self.resolve_vars_if_possible(ti.expected);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rustc_hir as hir;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::Visitor;
use rustc_hir::is_range_literal;
use rustc_hir::lang_items::LangItem;
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
use rustc_hir::{Expr, HirId};
Expand Down Expand Up @@ -1349,14 +1350,41 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
Applicability::MaybeIncorrect,
);
} else {
// Issue #104961, we need to add parentheses properly for compond expressions
// for example, `x.starts_with("hi".to_string() + "you")`
// should be `x.starts_with(&("hi".to_string() + "you"))`
let Some(body_id) = self.tcx.hir().maybe_body_owned_by(obligation.cause.body_id) else { return false; };
let body = self.tcx.hir().body(body_id);
let mut expr_finder = FindExprBySpan::new(span);
expr_finder.visit_expr(body.value);
let Some(expr) = expr_finder.result else { return false; };
let needs_parens = match expr.kind {
// parenthesize if needed (Issue #46756)
hir::ExprKind::Cast(_, _) | hir::ExprKind::Binary(_, _, _) => true,
// parenthesize borrows of range literals (Issue #54505)
_ if is_range_literal(expr) => true,
_ => false,
};

let is_mut = mut_ref_self_ty_satisfies_pred || ref_inner_ty_mut;
err.span_suggestion_verbose(
span.shrink_to_lo(),
&format!(
"consider{} borrowing here",
if is_mut { " mutably" } else { "" }
),
format!("&{}", if is_mut { "mut " } else { "" }),
let span = if needs_parens { span } else { span.shrink_to_lo() };
let sugg_prefix = format!("&{}", if is_mut { "mut " } else { "" });
let sugg_msg = &format!(
"consider{} borrowing here",
if is_mut { " mutably" } else { "" }
);

let suggestions = if !needs_parens {
vec![(span.shrink_to_lo(), format!("{}", sugg_prefix))]
} else {
vec![
(span.shrink_to_lo(), format!("{}(", sugg_prefix)),
(span.shrink_to_hi(), ")".to_string()),
]
};
err.multipart_suggestion_verbose(
sugg_msg,
suggestions,
Applicability::MaybeIncorrect,
);
}
Expand Down
9 changes: 5 additions & 4 deletions library/core/src/alloc/global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,18 +203,19 @@ pub unsafe trait GlobalAlloc {
ptr
}

/// Shrink or grow a block of memory to the given `new_size`.
/// Shrink or grow a block of memory to the given `new_size` in bytes.
/// The block is described by the given `ptr` pointer and `layout`.
///
/// If this returns a non-null pointer, then ownership of the memory block
/// referenced by `ptr` has been transferred to this allocator.
/// Any access to the old `ptr` is Undefined Behavior, even if the
/// allocation remained in-place. The newly returned pointer is the only valid pointer
/// for accessing this memory now.
///
/// The new memory block is allocated with `layout`,
/// but with the `size` updated to `new_size`. This new layout must be
/// used when deallocating the new memory block with `dealloc`. The range
/// `0..min(layout.size(), new_size)` of the new memory block is
/// but with the `size` updated to `new_size` in bytes.
/// This new layout must be used when deallocating the new memory block with `dealloc`.
/// The range `0..min(layout.size(), new_size)` of the new memory block is
/// guaranteed to have the same values as the original block.
///
/// If this method returns null, then ownership of the memory
Expand Down
28 changes: 22 additions & 6 deletions library/std/src/sys/unix/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,28 @@ mod imp {
// list.
let argv = ARGV.load(Ordering::Relaxed);
let argc = if argv.is_null() { 0 } else { ARGC.load(Ordering::Relaxed) };
(0..argc)
.map(|i| {
let cstr = CStr::from_ptr(*argv.offset(i) as *const libc::c_char);
OsStringExt::from_vec(cstr.to_bytes().to_vec())
})
.collect()
let mut args = Vec::with_capacity(argc as usize);
for i in 0..argc {
let ptr = *argv.offset(i) as *const libc::c_char;

// Some C commandline parsers (e.g. GLib and Qt) are replacing already
// handled arguments in `argv` with `NULL` and move them to the end. That
// means that `argc` might be bigger than the actual number of non-`NULL`
// pointers in `argv` at this point.
//
// To handle this we simply stop iterating at the first `NULL` argument.
//
// `argv` is also guaranteed to be `NULL`-terminated so any non-`NULL` arguments
// after the first `NULL` can safely be ignored.
if ptr.is_null() {
break;
}

let cstr = CStr::from_ptr(ptr);
args.push(OsStringExt::from_vec(cstr.to_bytes().to_vec()));
}

args
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions library/std/src/sys/windows/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1393,6 +1393,8 @@ fn symlink_junction_inner(original: &Path, junction: &Path) -> io::Result<()> {
let mut data = Align8([MaybeUninit::<u8>::uninit(); c::MAXIMUM_REPARSE_DATA_BUFFER_SIZE]);
let data_ptr = data.0.as_mut_ptr();
let db = data_ptr.cast::<c::REPARSE_MOUNTPOINT_DATA_BUFFER>();
// Zero the header to ensure it's fully initialized, including reserved parameters.
*db = mem::zeroed();
let buf = ptr::addr_of_mut!((*db).ReparseTarget).cast::<c::WCHAR>();
let mut i = 0;
// FIXME: this conversion is very hacky
Expand Down
9 changes: 3 additions & 6 deletions src/librustdoc/html/render/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use super::search_index::build_index;
use super::write_shared::write_shared;
use super::{
collect_spans_and_sources, print_sidebar, scrape_examples_help, sidebar_module_like, AllTypes,
LinkFromSrc, NameDoc, StylePath,
LinkFromSrc, StylePath,
};

use crate::clean::{self, types::ExternalLocation, ExternalCrate};
Expand Down Expand Up @@ -256,7 +256,7 @@ impl<'tcx> Context<'tcx> {
}

/// Construct a map of items shown in the sidebar to a plain-text summary of their docs.
fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<NameDoc>> {
fn build_sidebar_items(&self, m: &clean::Module) -> BTreeMap<String, Vec<String>> {
// BTreeMap instead of HashMap to get a sorted output
let mut map: BTreeMap<_, Vec<_>> = BTreeMap::new();
let mut inserted: FxHashMap<ItemType, FxHashSet<Symbol>> = FxHashMap::default();
Expand All @@ -274,10 +274,7 @@ impl<'tcx> Context<'tcx> {
if inserted.entry(short).or_default().insert(myname) {
let short = short.to_string();
let myname = myname.to_string();
map.entry(short).or_default().push((
myname,
Some(item.doc_value().map_or_else(String::new, |s| plain_text_summary(&s))),
));
map.entry(short).or_default().push(myname);
}
}

Expand Down
3 changes: 0 additions & 3 deletions src/librustdoc/html/render/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ use crate::scrape_examples::{CallData, CallLocation};
use crate::try_none;
use crate::DOC_RUST_LANG_ORG_CHANNEL;

/// A pair of name and its optional document.
pub(crate) type NameDoc = (String, Option<String>);

pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
crate::html::format::display_fn(move |f| {
if !v.ends_with('/') && !v.is_empty() { write!(f, "{}/", v) } else { f.write_str(v) }
Expand Down
6 changes: 1 addition & 5 deletions src/librustdoc/html/static/js/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,10 +455,7 @@ function loadCss(cssUrl) {
const ul = document.createElement("ul");
ul.className = "block " + shortty;

for (const item of filtered) {
const name = item[0];
const desc = item[1]; // can be null

for (const name of filtered) {
let path;
if (shortty === "mod") {
path = name + "/index.html";
Expand All @@ -468,7 +465,6 @@ function loadCss(cssUrl) {
const current_page = document.location.href.split("/").pop();
const link = document.createElement("a");
link.href = path;
link.title = desc;
if (path === current_page) {
link.className = "current";
}
Expand Down
27 changes: 0 additions & 27 deletions tests/rustdoc/markdown-summaries.rs

This file was deleted.

19 changes: 19 additions & 0 deletions tests/ui/const-generics/wrong-normalization.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// This test ensures that if implementation on projections is supported,
// it doesn't end in very weird cycle error.

#![crate_type = "lib"]

pub trait Identity {
type Identity: ?Sized;
}

impl<T: ?Sized> Identity for T {
type Identity = Self;
}

pub struct I8<const F: i8>;

impl <I8<{i8::MIN}> as Identity>::Identity {
//~^ ERROR no nominal type found for inherent implementation
pub fn foo(&self) {}
}
11 changes: 11 additions & 0 deletions tests/ui/const-generics/wrong-normalization.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
error[E0118]: no nominal type found for inherent implementation
--> $DIR/wrong-normalization.rs:16:6
|
LL | impl <I8<{i8::MIN}> as Identity>::Identity {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
|
= note: either implement a trait on it or create a newtype to wrap it instead

error: aborting due to previous error

For more information about this error, try `rustc --explain E0118`.
3 changes: 3 additions & 0 deletions tests/ui/impl-trait/nested-return-type2.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
// check-pass
// compile-flags: -Zvalidate-mir

// Using -Zvalidate-mir as a regression test for #107346.

trait Duh {}

Expand Down
2 changes: 1 addition & 1 deletion tests/ui/impl-trait/nested-return-type2.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
warning: opaque type `impl Trait<Assoc = impl Send>` does not satisfy its associated type bounds
--> $DIR/nested-return-type2.rs:25:24
--> $DIR/nested-return-type2.rs:28:24
|
LL | type Assoc: Duh;
| --- this associated type bound is unsatisfied for `impl Send`
Expand Down
16 changes: 16 additions & 0 deletions tests/ui/suggestions/issue-104961.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// run-rustfix

fn foo(x: &str) -> bool {
x.starts_with(&("hi".to_string() + " you"))
//~^ ERROR expected a `FnMut<(char,)>` closure, found `String`
}

fn foo2(x: &str) -> bool {
x.starts_with(&"hi".to_string())
//~^ ERROR expected a `FnMut<(char,)>` closure, found `String`
}

fn main() {
foo("hi you");
foo2("hi");
}
Loading

0 comments on commit 71f6675

Please sign in to comment.