Auto merge of #128748 - matthiaskrgr:rollup-dzvi5f7, r=matthiaskrgr

Rollup of 7 pull requests

Successful merges:

 - #128369 (rustc_lint: make `let-underscore-lock` translatable)
 - #128377 (Fix ICE Caused by Incorrectly Delaying E0107)
 - #128517 (Fallback to string formatting if source is not available for lint)
 - #128685 (Remove the root Cargo.lock from the rust-src component)
 - #128693 (rustdoc-search: account for numeric disambiguators on impls)
 - #128720 (Pass the right `ParamEnv` to `might_permit_raw_init_strict`)
 - #128736 (Fix rustdoc missing handling of remap-path-prefix option)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-08-06 22:12:39 +00:00
commit 0ddead30f0
18 changed files with 234 additions and 61 deletions

View File

@ -1,6 +1,6 @@
use rustc_middle::bug;
use rustc_middle::ty::layout::{LayoutCx, LayoutError, LayoutOf, TyAndLayout, ValidityRequirement};
use rustc_middle::ty::{ParamEnv, ParamEnvAnd, Ty, TyCtxt};
use rustc_middle::ty::{ParamEnvAnd, Ty, TyCtxt};
use rustc_target::abi::{Abi, FieldsShape, Scalar, Variants};
use crate::const_eval::{CanAccessMutGlobal, CheckAlignment, CompileTimeMachine};
@ -30,10 +30,10 @@ pub fn check_validity_requirement<'tcx>(
return Ok(!layout.abi.is_uninhabited());
}
let layout_cx = LayoutCx { tcx, param_env: param_env_and_ty.param_env };
if kind == ValidityRequirement::Uninit || tcx.sess.opts.unstable_opts.strict_init_checks {
might_permit_raw_init_strict(layout, tcx, kind)
might_permit_raw_init_strict(layout, &layout_cx, kind)
} else {
let layout_cx = LayoutCx { tcx, param_env: param_env_and_ty.param_env };
might_permit_raw_init_lax(layout, &layout_cx, kind)
}
}
@ -42,12 +42,12 @@ pub fn check_validity_requirement<'tcx>(
/// details.
fn might_permit_raw_init_strict<'tcx>(
ty: TyAndLayout<'tcx>,
tcx: TyCtxt<'tcx>,
cx: &LayoutCx<'tcx, TyCtxt<'tcx>>,
kind: ValidityRequirement,
) -> Result<bool, &'tcx LayoutError<'tcx>> {
let machine = CompileTimeMachine::new(CanAccessMutGlobal::No, CheckAlignment::Error);
let mut cx = InterpCx::new(tcx, rustc_span::DUMMY_SP, ParamEnv::reveal_all(), machine);
let mut cx = InterpCx::new(cx.tcx, rustc_span::DUMMY_SP, cx.param_env, machine);
let allocated = cx
.allocate(ty, MemoryKind::Machine(crate::const_eval::MemoryKind::Heap))

View File

@ -3700,6 +3700,11 @@ impl<'hir> OwnerNode<'hir> {
}
}
/// Check if node is an impl block.
pub fn is_impl_block(&self) -> bool {
matches!(self, OwnerNode::Item(Item { kind: ItemKind::Impl(_), .. }))
}
expect_methods_self! {
expect_item, &'hir Item<'hir>, OwnerNode::Item(n), n;
expect_foreign_item, &'hir ForeignItem<'hir>, OwnerNode::ForeignItem(n), n;

View File

@ -552,21 +552,34 @@ pub(crate) fn check_generic_arg_count(
synth_provided,
}
} else {
let num_missing_args = expected_max - provided;
// Check if associated type bounds are incorrectly written in impl block header like:
// ```
// trait Foo<T> {}
// impl Foo<T: Default> for u8 {}
// ```
let parent_is_impl_block = cx
.tcx()
.hir()
.parent_owner_iter(seg.hir_id)
.next()
.is_some_and(|(_, owner_node)| owner_node.is_impl_block());
if parent_is_impl_block {
let constraint_names: Vec<_> =
gen_args.constraints.iter().map(|b| b.ident.name).collect();
let param_names: Vec<_> = gen_params
.own_params
.iter()
.filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter
.map(|param| param.name)
.collect();
if constraint_names == param_names {
// We set this to true and delay emitting `WrongNumberOfGenericArgs`
// to provide a succinct error for cases like issue #113073
all_params_are_binded = true;
};
}
let constraint_names: Vec<_> =
gen_args.constraints.iter().map(|b| b.ident.name).collect();
let param_names: Vec<_> = gen_params
.own_params
.iter()
.filter(|param| !has_self || param.index != 0) // Assumes `Self` will always be the first parameter
.map(|param| param.name)
.collect();
if constraint_names == param_names {
// We set this to true and delay emitting `WrongNumberOfGenericArgs`
// to provide a succinct error for cases like issue #113073
all_params_are_binded = true;
};
let num_missing_args = expected_max - provided;
GenericArgsInfo::MissingTypesOrConsts {
num_missing_args,

View File

@ -518,8 +518,8 @@ lint_non_binding_let_multi_suggestion =
lint_non_binding_let_on_drop_type =
non-binding let on a type that implements `Drop`
lint_non_binding_let_on_sync_lock =
non-binding let on a synchronization lock
lint_non_binding_let_on_sync_lock = non-binding let on a synchronization lock
.label = this lock is not assigned to a binding and is immediately dropped
lint_non_binding_let_suggestion =
consider binding to an unused variable to avoid immediately dropping the value

View File

@ -104,7 +104,6 @@ const SYNC_GUARD_SYMBOLS: [Symbol; 3] = [
];
impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn check_local(&mut self, cx: &LateContext<'_>, local: &hir::LetStmt<'_>) {
if matches!(local.source, rustc_hir::LocalSource::AsyncFn) {
return;
@ -156,12 +155,12 @@ impl<'tcx> LateLintPass<'tcx> for LetUnderscore {
is_assign_desugar: matches!(local.source, rustc_hir::LocalSource::AssignDesugar(_)),
};
if is_sync_lock {
let mut span = MultiSpan::from_span(pat.span);
span.push_span_label(
pat.span,
"this lock is not assigned to a binding and is immediately dropped".to_string(),
let span = MultiSpan::from_span(pat.span);
cx.emit_span_lint(
LET_UNDERSCORE_LOCK,
span,
NonBindingLet::SyncLock { sub, pat: pat.span },
);
cx.emit_span_lint(LET_UNDERSCORE_LOCK, span, NonBindingLet::SyncLock { sub });
// Only emit let_underscore_drop for top-level `_` patterns.
} else if can_use_init.is_some() {
cx.emit_span_lint(LET_UNDERSCORE_DROP, local.span, NonBindingLet::DropType { sub });

View File

@ -957,6 +957,8 @@ pub struct BadOptAccessDiag<'a> {
pub enum NonBindingLet {
#[diag(lint_non_binding_let_on_sync_lock)]
SyncLock {
#[label]
pat: Span,
#[subdiagnostic]
sub: NonBindingLetSub,
},

View File

@ -458,8 +458,11 @@ fn lint_int_literal<'tcx>(
}
let span = if negative { type_limits.negated_expr_span.unwrap() } else { e.span };
let lit =
cx.sess().source_map().span_to_snippet(span).expect("must get snippet from literal");
let lit = cx
.sess()
.source_map()
.span_to_snippet(span)
.unwrap_or_else(|_| if negative { format!("-{v}") } else { v.to_string() });
let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
.map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
@ -485,6 +488,7 @@ fn lint_uint_literal<'tcx>(
ast::LitKind::Int(v, _) => v.get(),
_ => bug!(),
};
if lit_val < min || lit_val > max {
if let Node::Expr(par_e) = cx.tcx.parent_hir_node(e.hir_id) {
match par_e.kind {
@ -526,7 +530,7 @@ fn lint_uint_literal<'tcx>(
.sess()
.source_map()
.span_to_snippet(lit.span)
.expect("must get snippet from literal"),
.unwrap_or_else(|_| lit_val.to_string()),
min,
max,
},
@ -551,14 +555,14 @@ fn lint_literal<'tcx>(
}
ty::Uint(t) => lint_uint_literal(cx, e, lit, t),
ty::Float(t) => {
let is_infinite = match lit.node {
let (is_infinite, sym) = match lit.node {
ast::LitKind::Float(v, _) => match t {
// FIXME(f16_f128): add this check once `is_infinite` is reliable (ABI
// issues resolved).
ty::FloatTy::F16 => Ok(false),
ty::FloatTy::F32 => v.as_str().parse().map(f32::is_infinite),
ty::FloatTy::F64 => v.as_str().parse().map(f64::is_infinite),
ty::FloatTy::F128 => Ok(false),
ty::FloatTy::F16 => (Ok(false), v),
ty::FloatTy::F32 => (v.as_str().parse().map(f32::is_infinite), v),
ty::FloatTy::F64 => (v.as_str().parse().map(f64::is_infinite), v),
ty::FloatTy::F128 => (Ok(false), v),
},
_ => bug!(),
};
@ -572,7 +576,7 @@ fn lint_literal<'tcx>(
.sess()
.source_map()
.span_to_snippet(lit.span)
.expect("must get snippet from literal"),
.unwrap_or_else(|_| sym.to_string()),
},
);
}

View File

@ -918,7 +918,6 @@ impl Step for Src {
// translation code in `imported_source_files` in `src/librustc_metadata/rmeta/decoder.rs`
let dst_src = tarball.image_dir().join("lib/rustlib/src/rust");
let src_files = ["Cargo.lock"];
// This is the reduced set of paths which will become the rust-src component
// (essentially libstd and all of its path dependencies).
copy_src_dirs(
@ -937,9 +936,6 @@ impl Step for Src {
],
&dst_src,
);
for file in src_files.iter() {
builder.copy_link(&builder.src.join(file), &dst_src.join(file));
}
tarball.generate()
}

View File

@ -195,6 +195,7 @@ pub(crate) fn create_config(
lint_cap,
scrape_examples_options,
expanded_args,
remap_path_prefix,
..
}: RustdocOptions,
RenderOptions { document_private, .. }: &RenderOptions,
@ -247,6 +248,7 @@ pub(crate) fn create_config(
describe_lints,
crate_name,
test,
remap_path_prefix,
..Options::default()
};

View File

@ -390,13 +390,18 @@ function preLoadCss(cssUrl) {
if (splitAt !== -1) {
const implId = savedHash.slice(0, splitAt);
const assocId = savedHash.slice(splitAt + 1);
const implElem = document.getElementById(implId);
if (implElem && implElem.parentElement.tagName === "SUMMARY" &&
implElem.parentElement.parentElement.tagName === "DETAILS") {
onEachLazy(implElem.parentElement.parentElement.querySelectorAll(
const implElems = document.querySelectorAll(
`details > summary > section[id^="${implId}"]`,
);
onEachLazy(implElems, implElem => {
const numbered = /^(.+?)-([0-9]+)$/.exec(implElem.id);
if (implElem.id !== implId && (!numbered || numbered[1] !== implId)) {
return false;
}
return onEachLazy(implElem.parentElement.parentElement.querySelectorAll(
`[id^="${assocId}"]`),
item => {
const numbered = /([^-]+)-([0-9]+)/.exec(item.id);
const numbered = /^(.+?)-([0-9]+)$/.exec(item.id);
if (item.id === assocId || (numbered && numbered[1] === assocId)) {
openParentDetails(item);
item.scrollIntoView();
@ -404,10 +409,11 @@ function preLoadCss(cssUrl) {
setTimeout(() => {
window.location.replace("#" + item.id);
}, 0);
return true;
}
},
);
}
});
}
}
}

View File

@ -1,6 +1,7 @@
#![warn(clippy::uninit_vec)]
use std::mem::MaybeUninit;
use std::cell::UnsafeCell;
#[derive(Default)]
struct MyVec {
@ -12,6 +13,12 @@ union MyOwnMaybeUninit {
uninit: (),
}
// https://github.com/rust-lang/rust/issues/119620
unsafe fn requires_paramenv<S>() {
let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(1);
vec.set_len(1);
}
fn main() {
// with_capacity() -> set_len() should be detected
let mut vec: Vec<u8> = Vec::with_capacity(1000);

View File

@ -1,5 +1,17 @@
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:17:5
--> tests/ui/uninit_vec.rs:18:5
|
LL | let mut vec = Vec::<UnsafeCell<*mut S>>::with_capacity(1);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
LL | vec.set_len(1);
| ^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
= note: `-D clippy::uninit-vec` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::uninit_vec)]`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:24:5
|
LL | let mut vec: Vec<u8> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -8,11 +20,9 @@ LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
= note: `-D clippy::uninit-vec` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::uninit_vec)]`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:24:5
--> tests/ui/uninit_vec.rs:31:5
|
LL | vec.reserve(1000);
| ^^^^^^^^^^^^^^^^^^
@ -23,7 +33,7 @@ LL | vec.set_len(200);
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` on empty `Vec` creates out-of-bound values
--> tests/ui/uninit_vec.rs:31:5
--> tests/ui/uninit_vec.rs:38:5
|
LL | let mut vec: Vec<u8> = Vec::new();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -32,7 +42,7 @@ LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
error: calling `set_len()` on empty `Vec` creates out-of-bound values
--> tests/ui/uninit_vec.rs:38:5
--> tests/ui/uninit_vec.rs:45:5
|
LL | let mut vec: Vec<u8> = Default::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -41,7 +51,7 @@ LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
error: calling `set_len()` on empty `Vec` creates out-of-bound values
--> tests/ui/uninit_vec.rs:44:5
--> tests/ui/uninit_vec.rs:51:5
|
LL | let mut vec: Vec<u8> = Vec::default();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -50,7 +60,7 @@ LL | vec.set_len(200);
| ^^^^^^^^^^^^^^^^
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:61:5
--> tests/ui/uninit_vec.rs:68:5
|
LL | let mut vec: Vec<u8> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -61,7 +71,7 @@ LL | vec.set_len(200);
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:71:5
--> tests/ui/uninit_vec.rs:78:5
|
LL | my_vec.vec.reserve(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^
@ -72,7 +82,7 @@ LL | my_vec.vec.set_len(200);
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:77:5
--> tests/ui/uninit_vec.rs:84:5
|
LL | my_vec.vec = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -83,7 +93,7 @@ LL | my_vec.vec.set_len(200);
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:52:9
--> tests/ui/uninit_vec.rs:59:9
|
LL | let mut vec: Vec<u8> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -94,7 +104,7 @@ LL | vec.set_len(200);
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:56:9
--> tests/ui/uninit_vec.rs:63:9
|
LL | vec.reserve(1000);
| ^^^^^^^^^^^^^^^^^^
@ -105,7 +115,7 @@ LL | vec.set_len(200);
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: calling `set_len()` immediately after reserving a buffer creates uninitialized values
--> tests/ui/uninit_vec.rs:132:9
--> tests/ui/uninit_vec.rs:139:9
|
LL | let mut vec: Vec<T> = Vec::with_capacity(1000);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@ -115,5 +125,5 @@ LL | vec.set_len(10);
|
= help: initialize the buffer or wrap the content in `MaybeUninit`
error: aborting due to 11 previous errors
error: aborting due to 12 previous errors

View File

@ -41,3 +41,24 @@ assert-document-property: ({
"URL": "struct.ZyxwvutMethodDisambiguation.html#method.method_impl_disambiguation-1"
}, ENDS_WITH)
assert: "section:target"
// Checks that, if a type has two methods with the same name,
// and if it has multiple inherent impl blocks, that the numeric
// impl block's disambiguator is also acted upon.
go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=MultiImplBlockStruct->bool"
wait-for: "#search-tabs"
assert-count: ("a.result-method", 1)
assert-attribute: ("a.result-method", {
"href": "../lib2/another_mod/struct.MultiImplBlockStruct.html#impl-MultiImplBlockStruct/method.second_fn"
})
click: "a.result-method"
wait-for: "details:has(summary > #impl-MultiImplBlockStruct-1) > div section[id='method.second_fn']:target"
go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=MultiImplBlockStruct->u32"
wait-for: "#search-tabs"
assert-count: ("a.result-method", 1)
assert-attribute: ("a.result-method", {
"href": "../lib2/another_mod/struct.MultiImplBlockStruct.html#impl-MultiImplBlockTrait-for-MultiImplBlockStruct/method.second_fn"
})
click: "a.result-method"
wait-for: "details:has(summary > #impl-MultiImplBlockTrait-for-MultiImplBlockStruct) > div section[id='method.second_fn-1']:target"

View File

@ -1 +1,19 @@
pub fn tadam() {}
pub struct MultiImplBlockStruct;
impl MultiImplBlockStruct {
pub fn first_fn() {}
}
impl MultiImplBlockStruct {
pub fn second_fn(self) -> bool { true }
}
pub trait MultiImplBlockTrait {
fn first_fn();
fn second_fn(self) -> u32;
}
impl MultiImplBlockTrait for MultiImplBlockStruct {
fn first_fn() {}
fn second_fn(self) -> u32 { 1 }
}

View File

@ -0,0 +1,10 @@
// Regression test for remapped paths in rustdoc errors
// <https://github.com/rust-lang/rust/issues/69264>.
//@ compile-flags:-Z unstable-options --remap-path-prefix={{src-base}}=remapped_path
//@ rustc-env:RUST_BACKTRACE=0
#![deny(rustdoc::invalid_html_tags)]
/// </script>
pub struct Bar;

View File

@ -0,0 +1,14 @@
error: unopened HTML tag `script`
--> remapped_path/remap-path-prefix-lint.rs:9:5
|
LL | /// </script>
| ^^^^^^^^^
|
note: the lint level is defined here
--> remapped_path/remap-path-prefix-lint.rs:7:9
|
LL | #![deny(rustdoc::invalid_html_tags)]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to 1 previous error

View File

@ -0,0 +1,15 @@
trait Trait<Type> {
type Type;
fn one(&self, val: impl Trait<Type: Default>);
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
fn two<T: Trait<Type: Default>>(&self) -> T;
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
fn three<T>(&self) -> T where
T: Trait<Type: Default>,;
//~^ ERROR trait takes 1 generic argument but 0 generic arguments were supplied
}
fn main() {}

View File

@ -0,0 +1,51 @@
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/name-same-as-generic-type-issue-128249.rs:4:30
|
LL | fn one(&self, val: impl Trait<Type: Default>);
| ^^^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `Type`
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
|
LL | trait Trait<Type> {
| ^^^^^ ----
help: add missing generic argument
|
LL | fn one(&self, val: impl Trait<Type, Type: Default>);
| +++++
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/name-same-as-generic-type-issue-128249.rs:7:15
|
LL | fn two<T: Trait<Type: Default>>(&self) -> T;
| ^^^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `Type`
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
|
LL | trait Trait<Type> {
| ^^^^^ ----
help: add missing generic argument
|
LL | fn two<T: Trait<Type, Type: Default>>(&self) -> T;
| +++++
error[E0107]: trait takes 1 generic argument but 0 generic arguments were supplied
--> $DIR/name-same-as-generic-type-issue-128249.rs:11:12
|
LL | T: Trait<Type: Default>,;
| ^^^^^ expected 1 generic argument
|
note: trait defined here, with 1 generic parameter: `Type`
--> $DIR/name-same-as-generic-type-issue-128249.rs:1:7
|
LL | trait Trait<Type> {
| ^^^^^ ----
help: add missing generic argument
|
LL | T: Trait<Type, Type: Default>,;
| +++++
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0107`.