1
Fork 0

Auto merge of #124015 - GuillaumeGomez:rollup-s46ksxa, r=GuillaumeGomez

Rollup of 14 pull requests

Successful merges:

 - #120781 (Correct usage note on OpenOptions::append())
 - #121694 (sess: stabilize `-Zrelro-level` as `-Crelro-level`)
 - #122521 (doc(bootstrap): add top-level doc-comment to utils/tarball.rs)
 - #123491 (Fix ICE in `eval_body_using_ecx`)
 - #123574 (rustdoc: rename `issue-\d+.rs` tests to have meaningful names (part 6))
 - #123687 (Update ar_archive_writer to 0.2.0)
 - #123721 (Various visionOS fixes)
 - #123797 (Better graphviz output for SCCs and NLL constraints)
 - #123990 (Make `suggest_deref_closure_return` more idiomatic/easier to understand)
 - #123995 (Make `thir_tree` and `thir_flat` into hooks)
 - #123998 (Opaque types have no namespace)
 - #124001 (Fix docs for unstable_features lint.)
 - #124006 (Move size assertions for `mir::syntax` types into the same file)
 - #124011 (rustdoc: update the module-level docs of `rustdoc::clean`)

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2024-04-16 13:26:03 +00:00
commit 1dea922ea6
63 changed files with 349 additions and 219 deletions

View file

@ -210,9 +210,9 @@ dependencies = [
[[package]] [[package]]
name = "ar_archive_writer" name = "ar_archive_writer"
version = "0.1.5" version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9792d37ca5173d7e7f4fe453739a0671d0557915a030a383d6b866476bbc3e71" checksum = "f0c269894b6fe5e9d7ada0cf69b5bf847ff35bc25fc271f08e1d080fce80339a"
dependencies = [ dependencies = [
"object 0.32.2", "object 0.32.2",
] ]

View file

@ -26,7 +26,6 @@ use rustc_middle::ty::{self, RegionVid, Ty};
use rustc_middle::ty::{Region, TyCtxt}; use rustc_middle::ty::{Region, TyCtxt};
use rustc_span::symbol::{kw, Ident}; use rustc_span::symbol::{kw, Ident};
use rustc_span::Span; use rustc_span::Span;
use rustc_trait_selection::infer::type_variable::TypeVariableOrigin;
use rustc_trait_selection::infer::InferCtxtExt; use rustc_trait_selection::infer::InferCtxtExt;
use rustc_trait_selection::traits::{Obligation, ObligationCtxt}; use rustc_trait_selection::traits::{Obligation, ObligationCtxt};
@ -813,7 +812,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr); self.add_static_impl_trait_suggestion(&mut diag, *fr, fr_name, *outlived_fr);
self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr); self.suggest_adding_lifetime_params(&mut diag, *fr, *outlived_fr);
self.suggest_move_on_borrowing_closure(&mut diag); self.suggest_move_on_borrowing_closure(&mut diag);
self.suggest_deref_closure_value(&mut diag); self.suggest_deref_closure_return(&mut diag);
diag diag
} }
@ -1048,115 +1047,107 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// When encountering a lifetime error caused by the return type of a closure, check the /// When encountering a lifetime error caused by the return type of a closure, check the
/// corresponding trait bound and see if dereferencing the closure return value would satisfy /// corresponding trait bound and see if dereferencing the closure return value would satisfy
/// them. If so, we produce a structured suggestion. /// them. If so, we produce a structured suggestion.
fn suggest_deref_closure_value(&self, diag: &mut Diag<'_>) { fn suggest_deref_closure_return(&self, diag: &mut Diag<'_>) {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let map = tcx.hir();
// Get the closure return value and type. // Get the closure return value and type.
let body_id = map.body_owned_by(self.mir_def_id()); let closure_def_id = self.mir_def_id();
let body = &map.body(body_id); let hir::Node::Expr(
let value = &body.value.peel_blocks(); closure_expr @ hir::Expr {
let hir::Node::Expr(closure_expr) = tcx.hir_node_by_def_id(self.mir_def_id()) else { kind: hir::ExprKind::Closure(hir::Closure { body, .. }), ..
},
) = tcx.hir_node_by_def_id(closure_def_id)
else {
return; return;
}; };
let fn_call_id = tcx.parent_hir_id(self.mir_hir_id()); let ty::Closure(_, args) = *tcx.type_of(closure_def_id).instantiate_identity().kind()
let hir::Node::Expr(expr) = tcx.hir_node(fn_call_id) else { return }; else {
let def_id = map.enclosing_body_owner(fn_call_id); return;
let tables = tcx.typeck(def_id); };
let Some(return_value_ty) = tables.node_type_opt(value.hir_id) else { return }; let args = args.as_closure();
let return_value_ty = self.infcx.resolve_vars_if_possible(return_value_ty);
// Make sure that the parent expression is a method call.
let parent_expr_id = tcx.parent_hir_id(self.mir_hir_id());
let hir::Node::Expr(
parent_expr @ hir::Expr {
kind: hir::ExprKind::MethodCall(_, rcvr, call_args, _), ..
},
) = tcx.hir_node(parent_expr_id)
else {
return;
};
let typeck_results = tcx.typeck(self.mir_def_id());
// We don't use `ty.peel_refs()` to get the number of `*`s needed to get the root type. // We don't use `ty.peel_refs()` to get the number of `*`s needed to get the root type.
let mut ty = return_value_ty; let liberated_sig = tcx.liberate_late_bound_regions(closure_def_id.to_def_id(), args.sig());
let mut peeled_ty = liberated_sig.output();
let mut count = 0; let mut count = 0;
while let ty::Ref(_, t, _) = ty.kind() { while let ty::Ref(_, ref_ty, _) = *peeled_ty.kind() {
ty = *t; peeled_ty = ref_ty;
count += 1; count += 1;
} }
if !self.infcx.type_is_copy_modulo_regions(self.param_env, ty) { if !self.infcx.type_is_copy_modulo_regions(self.param_env, peeled_ty) {
return; return;
} }
// Build a new closure where the return type is an owned value, instead of a ref. // Build a new closure where the return type is an owned value, instead of a ref.
let Some(ty::Closure(did, args)) =
tables.node_type_opt(closure_expr.hir_id).as_ref().map(|ty| ty.kind())
else {
return;
};
let sig = args.as_closure().sig();
let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr( let closure_sig_as_fn_ptr_ty = Ty::new_fn_ptr(
tcx, tcx,
sig.map_bound(|s| { ty::Binder::dummy(tcx.mk_fn_sig(
let unsafety = hir::Unsafety::Normal; liberated_sig.inputs().iter().copied(),
use rustc_target::spec::abi; peeled_ty,
tcx.mk_fn_sig( liberated_sig.c_variadic,
[s.inputs()[0]], hir::Unsafety::Normal,
s.output().peel_refs(), rustc_target::spec::abi::Abi::Rust,
s.c_variadic, )),
unsafety,
abi::Abi::Rust,
)
}),
); );
let parent_args = GenericArgs::identity_for_item( let closure_ty = Ty::new_closure(
tcx, tcx,
tcx.typeck_root_def_id(self.mir_def_id().to_def_id()), closure_def_id.to_def_id(),
ty::ClosureArgs::new(
tcx,
ty::ClosureArgsParts {
parent_args: args.parent_args(),
closure_kind_ty: args.kind_ty(),
tupled_upvars_ty: args.tupled_upvars_ty(),
closure_sig_as_fn_ptr_ty,
},
)
.args,
); );
let closure_kind = args.as_closure().kind();
let closure_kind_ty = Ty::from_closure_kind(tcx, closure_kind);
let tupled_upvars_ty = self
.infcx
.next_ty_var(TypeVariableOrigin { param_def_id: None, span: closure_expr.span });
let closure_args = ty::ClosureArgs::new(
tcx,
ty::ClosureArgsParts {
parent_args,
closure_kind_ty,
closure_sig_as_fn_ptr_ty,
tupled_upvars_ty,
},
);
let closure_ty = Ty::new_closure(tcx, *did, closure_args.args);
let closure_ty = tcx.erase_regions(closure_ty);
let hir::ExprKind::MethodCall(_, rcvr, args, _) = expr.kind else { return }; let Some((closure_arg_pos, _)) =
let Some(pos) = args call_args.iter().enumerate().find(|(_, arg)| arg.hir_id == closure_expr.hir_id)
.iter()
.enumerate()
.find(|(_, arg)| arg.hir_id == closure_expr.hir_id)
.map(|(i, _)| i)
else { else {
return; return;
}; };
// The found `Self` type of the method call.
let Some(possible_rcvr_ty) = tables.node_type_opt(rcvr.hir_id) else { return };
let Some(method_def_id) = tables.type_dependent_def_id(expr.hir_id) else { return };
// Get the type for the parameter corresponding to the argument the closure with the // Get the type for the parameter corresponding to the argument the closure with the
// lifetime error we had. // lifetime error we had.
let Some(input) = tcx let Some(method_def_id) = typeck_results.type_dependent_def_id(parent_expr.hir_id) else {
return;
};
let Some(input_arg) = tcx
.fn_sig(method_def_id) .fn_sig(method_def_id)
.instantiate_identity() .skip_binder()
.inputs() .inputs()
.skip_binder() .skip_binder()
// Methods have a `self` arg, so `pos` is actually `+ 1` to match the method call arg. // Methods have a `self` arg, so `pos` is actually `+ 1` to match the method call arg.
.get(pos + 1) .get(closure_arg_pos + 1)
else { else {
return; return;
}; };
// If this isn't a param, then we can't substitute a new closure.
trace!(?input); let ty::Param(closure_param) = input_arg.kind() else { return };
let ty::Param(closure_param) = input.kind() else { return };
// Get the arguments for the found method, only specifying that `Self` is the receiver type. // Get the arguments for the found method, only specifying that `Self` is the receiver type.
let Some(possible_rcvr_ty) = typeck_results.node_type_opt(rcvr.hir_id) else { return };
let args = GenericArgs::for_item(tcx, method_def_id, |param, _| { let args = GenericArgs::for_item(tcx, method_def_id, |param, _| {
if param.index == 0 { if param.index == 0 {
possible_rcvr_ty.into() possible_rcvr_ty.into()
} else if param.index == closure_param.index { } else if param.index == closure_param.index {
closure_ty.into() closure_ty.into()
} else { } else {
self.infcx.var_for_def(expr.span, param) self.infcx.var_for_def(parent_expr.span, param)
} }
}); });
@ -1170,7 +1161,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
if ocx.select_all_or_error().is_empty() { if ocx.select_all_or_error().is_empty() {
diag.span_suggestion_verbose( diag.span_suggestion_verbose(
value.span.shrink_to_lo(), tcx.hir().body(*body).value.peel_blocks().span.shrink_to_lo(),
"dereference the return value", "dereference the return value",
"*".repeat(count), "*".repeat(count),
Applicability::MachineApplicable, Applicability::MachineApplicable,

View file

@ -6,7 +6,38 @@ use std::borrow::Cow;
use std::io::{self, Write}; use std::io::{self, Write};
use super::*; use super::*;
use itertools::Itertools;
use rustc_graphviz as dot; use rustc_graphviz as dot;
use rustc_middle::ty::UniverseIndex;
fn render_outlives_constraint(constraint: &OutlivesConstraint<'_>) -> String {
match constraint.locations {
Locations::All(_) => "All(...)".to_string(),
Locations::Single(loc) => format!("{loc:?}"),
}
}
fn render_universe(u: UniverseIndex) -> String {
if u.is_root() {
return "".to_string();
}
format!("/{:?}", u)
}
fn render_region_vid(rvid: RegionVid, regioncx: &RegionInferenceContext<'_>) -> String {
let universe_str = render_universe(regioncx.region_definition(rvid).universe);
let external_name_str = if let Some(external_name) =
regioncx.region_definition(rvid).external_name.and_then(|e| e.get_name())
{
format!(" ({external_name})")
} else {
"".to_string()
};
format!("{:?}{universe_str}{external_name_str}", rvid)
}
impl<'tcx> RegionInferenceContext<'tcx> { impl<'tcx> RegionInferenceContext<'tcx> {
/// Write out the region constraint graph. /// Write out the region constraint graph.
@ -46,10 +77,10 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for RawConstraints<'a, 'tcx> {
Some(dot::LabelText::LabelStr(Cow::Borrowed("box"))) Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
} }
fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> { fn node_label(&'this self, n: &RegionVid) -> dot::LabelText<'this> {
dot::LabelText::LabelStr(format!("{n:?}").into()) dot::LabelText::LabelStr(render_region_vid(*n, self.regioncx).into())
} }
fn edge_label(&'this self, e: &OutlivesConstraint<'tcx>) -> dot::LabelText<'this> { fn edge_label(&'this self, e: &OutlivesConstraint<'tcx>) -> dot::LabelText<'this> {
dot::LabelText::LabelStr(format!("{:?}", e.locations).into()) dot::LabelText::LabelStr(render_outlives_constraint(e).into())
} }
} }
@ -96,8 +127,9 @@ impl<'a, 'this, 'tcx> dot::Labeller<'this> for SccConstraints<'a, 'tcx> {
Some(dot::LabelText::LabelStr(Cow::Borrowed("box"))) Some(dot::LabelText::LabelStr(Cow::Borrowed("box")))
} }
fn node_label(&'this self, n: &ConstraintSccIndex) -> dot::LabelText<'this> { fn node_label(&'this self, n: &ConstraintSccIndex) -> dot::LabelText<'this> {
let nodes = &self.nodes_per_scc[*n]; let nodes_str =
dot::LabelText::LabelStr(format!("{n:?} = {nodes:?}").into()) self.nodes_per_scc[*n].iter().map(|n| render_region_vid(*n, self.regioncx)).join(", ");
dot::LabelText::LabelStr(format!("SCC({n}) = {{{nodes_str}}}", n = n.as_usize()).into())
} }
} }

View file

@ -1562,7 +1562,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
// Because this free region must be in the ROOT universe, we // Because this free region must be in the ROOT universe, we
// know it cannot contain any bound universes. // know it cannot contain any bound universes.
assert!(self.scc_universes[longer_fr_scc] == ty::UniverseIndex::ROOT); assert!(self.scc_universes[longer_fr_scc].is_root());
debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none()); debug_assert!(self.scc_values.placeholders_contained_in(longer_fr_scc).next().is_none());
// Only check all of the relations for the main representative of each // Only check all of the relations for the main representative of each

View file

@ -213,7 +213,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let scc = self.constraint_sccs.scc(vid); let scc = self.constraint_sccs.scc(vid);
// Special handling of higher-ranked regions. // Special handling of higher-ranked regions.
if self.scc_universes[scc] != ty::UniverseIndex::ROOT { if !self.scc_universes[scc].is_root() {
match self.scc_values.placeholders_contained_in(scc).enumerate().last() { match self.scc_values.placeholders_contained_in(scc).enumerate().last() {
// If the region contains a single placeholder then they're equal. // If the region contains a single placeholder then they're equal.
Some((0, placeholder)) => { Some((0, placeholder)) => {

View file

@ -5,7 +5,7 @@ edition = "2021"
[dependencies] [dependencies]
# tidy-alphabetical-start # tidy-alphabetical-start
ar_archive_writer = "0.1.5" ar_archive_writer = "0.2.0"
bitflags = "2.4.1" bitflags = "2.4.1"
cc = "1.0.90" cc = "1.0.90"
itertools = "0.12" itertools = "0.12"

View file

@ -285,14 +285,7 @@ impl<'a> ArArchiveBuilder<'a> {
.tempfile_in(output.parent().unwrap_or_else(|| Path::new(""))) .tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
.map_err(|err| io_error_context("couldn't create a temp file", err))?; .map_err(|err| io_error_context("couldn't create a temp file", err))?;
write_archive_to_stream( write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?;
archive_tmpfile.as_file_mut(),
&entries,
true,
archive_kind,
true,
false,
)?;
let any_entries = !entries.is_empty(); let any_entries = !entries.is_empty();
drop(entries); drop(entries);

View file

@ -2059,7 +2059,7 @@ fn add_library_search_dirs(cmd: &mut dyn Linker, sess: &Session, self_contained:
/// Add options making relocation sections in the produced ELF files read-only /// Add options making relocation sections in the produced ELF files read-only
/// and suppressing lazy binding. /// and suppressing lazy binding.
fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) { fn add_relro_args(cmd: &mut dyn Linker, sess: &Session) {
match sess.opts.unstable_opts.relro_level.unwrap_or(sess.target.relro_level) { match sess.opts.cg.relro_level.unwrap_or(sess.target.relro_level) {
RelroLevel::Full => cmd.full_relro(), RelroLevel::Full => cmd.full_relro(),
RelroLevel::Partial => cmd.partial_relro(), RelroLevel::Partial => cmd.partial_relro(),
RelroLevel::Off => cmd.no_relro(), RelroLevel::Off => cmd.no_relro(),
@ -3038,9 +3038,10 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
|| sdkroot.contains("MacOSX.platform") => {} || sdkroot.contains("MacOSX.platform") => {}
"watchsimulator" "watchsimulator"
if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {} if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {}
"visionos" "xros"
if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {} if sdkroot.contains("XRSimulator.platform")
"visionossimulator" || sdkroot.contains("MacOSX.platform") => {}
"xrsimulator"
if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {} if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {}
// Ignore `SDKROOT` if it's not a valid path. // Ignore `SDKROOT` if it's not a valid path.
_ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {} _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}

View file

@ -207,7 +207,6 @@ impl DefKind {
| DefKind::Enum | DefKind::Enum
| DefKind::Variant | DefKind::Variant
| DefKind::Trait | DefKind::Trait
| DefKind::OpaqueTy
| DefKind::TyAlias | DefKind::TyAlias
| DefKind::ForeignTy | DefKind::ForeignTy
| DefKind::TraitAlias | DefKind::TraitAlias
@ -234,7 +233,8 @@ impl DefKind {
| DefKind::Use | DefKind::Use
| DefKind::ForeignMod | DefKind::ForeignMod
| DefKind::GlobalAsm | DefKind::GlobalAsm
| DefKind::Impl { .. } => None, | DefKind::Impl { .. }
| DefKind::OpaqueTy => None,
} }
} }

View file

@ -624,6 +624,7 @@ fn test_codegen_options_tracking_hash() {
tracked!(profile_generate, SwitchWithOptPath::Enabled(None)); tracked!(profile_generate, SwitchWithOptPath::Enabled(None));
tracked!(profile_use, Some(PathBuf::from("abc"))); tracked!(profile_use, Some(PathBuf::from("abc")));
tracked!(relocation_model, Some(RelocModel::Pic)); tracked!(relocation_model, Some(RelocModel::Pic));
tracked!(relro_level, Some(RelroLevel::Full));
tracked!(soft_float, true); tracked!(soft_float, true);
tracked!(split_debuginfo, Some(SplitDebuginfo::Packed)); tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0)); tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
@ -822,7 +823,6 @@ fn test_unstable_options_tracking_hash() {
tracked!(profile_sample_use, Some(PathBuf::from("abc"))); tracked!(profile_sample_use, Some(PathBuf::from("abc")));
tracked!(profiler_runtime, "abc".to_string()); tracked!(profiler_runtime, "abc".to_string());
tracked!(relax_elf_relocations, Some(true)); tracked!(relax_elf_relocations, Some(true));
tracked!(relro_level, Some(RelroLevel::Full));
tracked!(remap_cwd_prefix, Some(PathBuf::from("abc"))); tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
tracked!(sanitizer, SanitizerSet::ADDRESS); tracked!(sanitizer, SanitizerSet::ADDRESS);
tracked!(sanitizer_cfi_canonical_jump_tables, None); tracked!(sanitizer_cfi_canonical_jump_tables, None);

View file

@ -102,4 +102,10 @@ declare_hooks! {
/// turn a deserialized `DefPathHash` into its current `DefId`. /// turn a deserialized `DefPathHash` into its current `DefId`.
/// Will fetch a DefId from a DefPathHash for a foreign crate. /// Will fetch a DefId from a DefPathHash for a foreign crate.
hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId; hook def_path_hash_to_def_id_extern(hash: DefPathHash, stable_crate_id: StableCrateId) -> DefId;
/// Create a THIR tree for debugging.
hook thir_tree(key: LocalDefId) -> String;
/// Create a list-like THIR representation for debugging.
hook thir_flat(key: LocalDefId) -> String;
} }

View file

@ -1823,9 +1823,7 @@ mod size_asserts {
static_assert_size!(LocalDecl<'_>, 40); static_assert_size!(LocalDecl<'_>, 40);
static_assert_size!(SourceScopeData<'_>, 64); static_assert_size!(SourceScopeData<'_>, 64);
static_assert_size!(Statement<'_>, 32); static_assert_size!(Statement<'_>, 32);
static_assert_size!(StatementKind<'_>, 16);
static_assert_size!(Terminator<'_>, 112); static_assert_size!(Terminator<'_>, 112);
static_assert_size!(TerminatorKind<'_>, 96);
static_assert_size!(VarDebugInfo<'_>, 88); static_assert_size!(VarDebugInfo<'_>, 88);
// tidy-alphabetical-end // tidy-alphabetical-end
} }

View file

@ -1463,5 +1463,6 @@ mod size_asserts {
static_assert_size!(PlaceElem<'_>, 24); static_assert_size!(PlaceElem<'_>, 24);
static_assert_size!(Rvalue<'_>, 40); static_assert_size!(Rvalue<'_>, 40);
static_assert_size!(StatementKind<'_>, 16); static_assert_size!(StatementKind<'_>, 16);
static_assert_size!(TerminatorKind<'_>, 96);
// tidy-alphabetical-end // tidy-alphabetical-end
} }

View file

@ -474,20 +474,6 @@ rustc_queries! {
desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) } desc { |tcx| "building THIR for `{}`", tcx.def_path_str(key) }
} }
/// Create a THIR tree for debugging.
query thir_tree(key: LocalDefId) -> &'tcx String {
no_hash
arena_cache
desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key) }
}
/// Create a list-like THIR representation for debugging.
query thir_flat(key: LocalDefId) -> &'tcx String {
no_hash
arena_cache
desc { |tcx| "constructing flat THIR representation for `{}`", tcx.def_path_str(key) }
}
/// Set of all the `DefId`s in this crate that have MIR associated with /// Set of all the `DefId`s in this crate that have MIR associated with
/// them. This includes all the body owners, but also things like struct /// them. This includes all the body owners, but also things like struct
/// constructors. /// constructors.

View file

@ -34,6 +34,6 @@ pub fn provide(providers: &mut Providers) {
build::closure_saved_names_of_captured_variables; build::closure_saved_names_of_captured_variables;
providers.check_unsafety = check_unsafety::check_unsafety; providers.check_unsafety = check_unsafety::check_unsafety;
providers.thir_body = thir::cx::thir_body; providers.thir_body = thir::cx::thir_body;
providers.thir_tree = thir::print::thir_tree; providers.hooks.thir_tree = thir::print::thir_tree;
providers.thir_flat = thir::print::thir_flat; providers.hooks.thir_flat = thir::print::thir_flat;
} }

View file

@ -1,10 +1,11 @@
use rustc_middle::query::TyCtxtAt;
use rustc_middle::thir::*; use rustc_middle::thir::*;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty;
use rustc_span::def_id::LocalDefId; use rustc_span::def_id::LocalDefId;
use std::fmt::{self, Write}; use std::fmt::{self, Write};
pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { pub(crate) fn thir_tree(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String {
match super::cx::thir_body(tcx, owner_def) { match super::cx::thir_body(*tcx, owner_def) {
Ok((thir, _)) => { Ok((thir, _)) => {
let thir = thir.steal(); let thir = thir.steal();
let mut printer = ThirPrinter::new(&thir); let mut printer = ThirPrinter::new(&thir);
@ -15,8 +16,8 @@ pub(crate) fn thir_tree(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String {
} }
} }
pub(crate) fn thir_flat(tcx: TyCtxt<'_>, owner_def: LocalDefId) -> String { pub(crate) fn thir_flat(tcx: TyCtxtAt<'_>, owner_def: LocalDefId) -> String {
match super::cx::thir_body(tcx, owner_def) { match super::cx::thir_body(*tcx, owner_def) {
Ok((thir, _)) => format!("{:#?}", thir.steal()), Ok((thir, _)) => format!("{:#?}", thir.steal()),
Err(_) => "error".into(), Err(_) => "error".into(),
} }

View file

@ -1534,6 +1534,8 @@ options! {
relocation_model: Option<RelocModel> = (None, parse_relocation_model, [TRACKED], relocation_model: Option<RelocModel> = (None, parse_relocation_model, [TRACKED],
"control generation of position-independent code (PIC) \ "control generation of position-independent code (PIC) \
(`rustc --print relocation-models` for details)"), (`rustc --print relocation-models` for details)"),
relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
"choose which RELRO level to use"),
remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED], remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED],
"output remarks for these optimization passes (space separated, or \"all\")"), "output remarks for these optimization passes (space separated, or \"all\")"),
rpath: bool = (false, parse_bool, [UNTRACKED], rpath: bool = (false, parse_bool, [UNTRACKED],
@ -1881,8 +1883,6 @@ options! {
"randomize the layout of types (default: no)"), "randomize the layout of types (default: no)"),
relax_elf_relocations: Option<bool> = (None, parse_opt_bool, [TRACKED], relax_elf_relocations: Option<bool> = (None, parse_opt_bool, [TRACKED],
"whether ELF relocations can be relaxed"), "whether ELF relocations can be relaxed"),
relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
"choose which RELRO level to use"),
remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED], remap_cwd_prefix: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
"remap paths under the current working directory to this path prefix"), "remap paths under the current working directory to this path prefix"),
remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED], remap_path_scope: RemapPathScopeComponents = (RemapPathScopeComponents::all(), parse_remap_path_scope, [TRACKED],

View file

@ -573,7 +573,7 @@ impl Session {
let dbg_opts = &self.opts.unstable_opts; let dbg_opts = &self.opts.unstable_opts;
let relro_level = dbg_opts.relro_level.unwrap_or(self.target.relro_level); let relro_level = self.opts.cg.relro_level.unwrap_or(self.target.relro_level);
// Only enable this optimization by default if full relro is also enabled. // Only enable this optimization by default if full relro is also enabled.
// In this case, lazy binding was already unavailable, so nothing is lost. // In this case, lazy binding was already unavailable, so nothing is lost.

View file

@ -298,6 +298,7 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
|| sdkroot.contains("WatchOS.platform") || sdkroot.contains("WatchOS.platform")
|| sdkroot.contains("WatchSimulator.platform") || sdkroot.contains("WatchSimulator.platform")
|| sdkroot.contains("XROS.platform") || sdkroot.contains("XROS.platform")
|| sdkroot.contains("XRSimulator.platform")
{ {
env_remove.push("SDKROOT".into()) env_remove.push("SDKROOT".into())
} }

View file

@ -984,7 +984,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Already reported in the query. // Already reported in the query.
SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) | SelectionError::NotConstEvaluatable(NotConstEvaluatable::Error(guar)) |
// Already reported. // Already reported.
Overflow(OverflowError::Error(guar)) => return guar, Overflow(OverflowError::Error(guar)) => {
self.set_tainted_by_errors(guar);
return guar
},
Overflow(_) => { Overflow(_) => {
bug!("overflow should be handled before the `report_selection_error` path"); bug!("overflow should be handled before the `report_selection_error` path");

View file

@ -87,6 +87,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
} else if lang_items.sized_trait() == Some(def_id) { } else if lang_items.sized_trait() == Some(def_id) {
// Sized is never implementable by end-users, it is // Sized is never implementable by end-users, it is
// always automatically computed. // always automatically computed.
// FIXME: Consider moving this check to the top level as it
// may also be useful for predicates other than `Sized`
// Error type cannot possibly implement `Sized` (fixes #123154)
if let Err(e) = obligation.predicate.skip_binder().self_ty().error_reported() {
return Err(SelectionError::Overflow(e.into()));
}
let sized_conditions = self.sized_conditions(obligation); let sized_conditions = self.sized_conditions(obligation);
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates); self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
} else if lang_items.unsize_trait() == Some(def_id) { } else if lang_items.unsize_trait() == Some(def_id) {

View file

@ -91,8 +91,8 @@ fn adt_sized_constraint<'tcx>(
let tail_ty = tcx.type_of(tail_def.did).instantiate_identity(); let tail_ty = tcx.type_of(tail_def.did).instantiate_identity();
let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?; let constraint_ty = sized_constraint_for_ty(tcx, tail_ty)?;
if constraint_ty.references_error() { if let Err(guar) = constraint_ty.error_reported() {
return None; return Some(ty::EarlyBinder::bind(Ty::new_error(tcx, guar)));
} }
// perf hack: if there is a `constraint_ty: Sized` bound, then we know // perf hack: if there is a `constraint_ty: Sized` bound, then we know

View file

@ -346,6 +346,11 @@ impl UniverseIndex {
pub fn cannot_name(self, other: UniverseIndex) -> bool { pub fn cannot_name(self, other: UniverseIndex) -> bool {
self < other self < other
} }
/// Returns `true` if `self` is the root universe, otherwise false.
pub fn is_root(self) -> bool {
self == Self::ROOT
}
} }
impl Default for UniverseIndex { impl Default for UniverseIndex {

View file

@ -980,15 +980,21 @@ impl OpenOptions {
/// Note that setting `.write(true).append(true)` has the same effect as /// Note that setting `.write(true).append(true)` has the same effect as
/// setting only `.append(true)`. /// setting only `.append(true)`.
/// ///
/// For most filesystems, the operating system guarantees that all writes are /// Append mode guarantees that writes will be positioned at the current end of file,
/// atomic: no writes get mangled because another process writes at the same /// even when there are other processes or threads appending to the same file. This is
/// time. /// unlike <code>[seek]\([SeekFrom]::[End]\(0))</code> followed by `write()`, which
/// has a race between seeking and writing during which another writer can write, with
/// our `write()` overwriting their data.
/// ///
/// One maybe obvious note when using append-mode: make sure that all data /// Keep in mind that this does not necessarily guarantee that data appended by
/// that belongs together is written to the file in one operation. This /// different processes or threads does not interleave. The amount of data accepted a
/// can be done by concatenating strings before passing them to [`write()`], /// single `write()` call depends on the operating system and file system. A
/// or using a buffered writer (with a buffer of adequate size), /// successful `write()` is allowed to write only part of the given data, so even if
/// and calling [`flush()`] when the message is complete. /// you're careful to provide the whole message in a single call to `write()`, there
/// is no guarantee that it will be written out in full. If you rely on the filesystem
/// accepting the message in a single write, make sure that all data that belongs
/// together is written in one operation. This can be done by concatenating strings
/// before passing them to [`write()`].
/// ///
/// If a file is opened with both read and append access, beware that after /// If a file is opened with both read and append access, beware that after
/// opening, and after every write, the position for reading may be set at the /// opening, and after every write, the position for reading may be set at the
@ -1003,6 +1009,9 @@ impl OpenOptions {
/// [`write()`]: Write::write "io::Write::write" /// [`write()`]: Write::write "io::Write::write"
/// [`flush()`]: Write::flush "io::Write::flush" /// [`flush()`]: Write::flush "io::Write::flush"
/// [stream_position]: Seek::stream_position "io::Seek::stream_position" /// [stream_position]: Seek::stream_position "io::Seek::stream_position"
/// [seek]: Seek::seek "io::Seek::seek"
/// [Current]: SeekFrom::Current "io::SeekFrom::Current"
/// [End]: SeekFrom::End "io::SeekFrom::End"
/// ///
/// # Examples /// # Examples
/// ///

View file

@ -11,18 +11,6 @@ use crate::os::linux::process::PidFd;
#[cfg(target_os = "linux")] #[cfg(target_os = "linux")]
use crate::os::unix::io::AsRawFd; use crate::os::unix::io::AsRawFd;
#[cfg(any(
target_os = "macos",
target_os = "watchos",
target_os = "visionos",
target_os = "tvos",
target_os = "freebsd",
all(target_os = "linux", target_env = "gnu"),
all(target_os = "linux", target_env = "musl"),
target_os = "nto",
))]
use crate::sys::weak::weak;
#[cfg(target_os = "vxworks")] #[cfg(target_os = "vxworks")]
use libc::RTP_ID as pid_t; use libc::RTP_ID as pid_t;
@ -466,6 +454,7 @@ impl Command {
envp: Option<&CStringArray>, envp: Option<&CStringArray>,
) -> io::Result<Option<Process>> { ) -> io::Result<Option<Process>> {
use crate::mem::MaybeUninit; use crate::mem::MaybeUninit;
use crate::sys::weak::weak;
use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified}; use crate::sys::{self, cvt_nz, unix_sigpipe_attr_specified};
if self.get_gid().is_some() if self.get_gid().is_some()

View file

@ -1,3 +1,10 @@
//! Facilitates the management and generation of tarballs.
//!
//! Tarballs efficiently hold Rust compiler build artifacts and
//! capture a snapshot of each boostrap stage.
//! In uplifting, a tarball from Stage N captures essential components
//! to assemble Stage N + 1 compiler.
use std::{ use std::{
path::{Path, PathBuf}, path::{Path, PathBuf},
process::Command, process::Command,

View file

@ -479,6 +479,26 @@ then `-C target-feature=+crt-static` "wins" over `-C relocation-model=pic`,
and the linker is instructed (`-static`) to produce a statically linked and the linker is instructed (`-static`) to produce a statically linked
but not position-independent executable. but not position-independent executable.
## relro-level
This flag controls what level of RELRO (Relocation Read-Only) is enabled. RELRO is an exploit
mitigation which makes the Global Offset Table (GOT) read-only.
Supported values for this option are:
- `off`: Dynamically linked functions are resolved lazily and the GOT is writable.
- `partial`: Dynamically linked functions are resolved lazily and written into the Procedure
Linking Table (PLT) part of the GOT (`.got.plt`). The non-PLT part of the GOT (`.got`) is made
read-only and both are moved to prevent writing from buffer overflows.
- `full`: Dynamically linked functions are resolved at the start of program execution and the
Global Offset Table (`.got`/`.got.plt`) is populated eagerly and then made read-only. The GOT is
also moved to prevent writing from buffer overflows. Full RELRO uses more memory and increases
process startup time.
This flag is ignored on platforms where RELRO is not supported (targets which do not use the ELF
binary format), such as Windows or macOS. Each rustc target has its own default for RELRO. rustc
enables Full RELRO by default on platforms where it is supported.
## remark ## remark
This flag lets you print remarks for optimization passes. This flag lets you print remarks for optimization passes.

View file

@ -1,5 +1,25 @@
//! This module contains the "cleaned" pieces of the AST, and the functions //! This module defines the primary IR[^1] used in rustdoc together with the procedures that
//! that clean them. //! transform rustc data types into it.
//!
//! This IR — commonly referred to as the *cleaned AST* — is modeled after the [AST][ast].
//!
//! There are two kinds of transformation — *cleaning* — procedures:
//!
//! 1. Cleans [HIR][hir] types. Used for user-written code and inlined local re-exports
//! both found in the local crate.
//! 2. Cleans [`rustc_middle::ty`] types. Used for inlined cross-crate re-exports and anything
//! output by the trait solver (e.g., when synthesizing blanket and auto-trait impls).
//! They usually have `ty` or `middle` in their name.
//!
//! Their name is prefixed by `clean_`.
//!
//! Both the HIR and the `rustc_middle::ty` IR are quite removed from the source code.
//! The cleaned AST on the other hand is closer to it which simplifies the rendering process.
//! Furthermore, operating on a single IR instead of two avoids duplicating efforts down the line.
//!
//! This IR is consumed by both the HTML and the JSON backend.
//!
//! [^1]: Intermediate representation.
mod auto_trait; mod auto_trait;
mod blanket_impl; mod blanket_impl;

View file

@ -270,7 +270,6 @@ impl<'a> LintExtractor<'a> {
if matches!( if matches!(
lint.name.as_str(), lint.name.as_str(),
"unused_features" // broken lint "unused_features" // broken lint
| "unstable_features" // deprecated
) { ) {
return Ok(()); return Ok(());
} }

View file

@ -1,12 +0,0 @@
//@ known-bug: #123154
struct AA {
pub data: [&usize]
}
impl AA {
const fn new() -> Self { }
}
static AA = AA::new();
fn main() { }

View file

@ -3,20 +3,20 @@ include ../tools.mk
# only-linux # only-linux
# #
# This tests the different -Zrelro-level values, and makes sure that they work properly. # This tests the different -Crelro-level values, and makes sure that they work properly.
all: all:
# Ensure that binaries built with the full relro level links them with both # Ensure that binaries built with the full relro level links them with both
# RELRO and BIND_NOW for doing eager symbol resolving. # RELRO and BIND_NOW for doing eager symbol resolving.
$(RUSTC) -Zrelro-level=full hello.rs $(RUSTC) -Crelro-level=full hello.rs
readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO
readelf -d $(TMPDIR)/hello | grep -q BIND_NOW readelf -d $(TMPDIR)/hello | grep -q BIND_NOW
$(RUSTC) -Zrelro-level=partial hello.rs $(RUSTC) -Crelro-level=partial hello.rs
readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO
# Ensure that we're *not* built with RELRO when setting it to off. We do # Ensure that we're *not* built with RELRO when setting it to off. We do
# not want to check for BIND_NOW however, as the linker might have that # not want to check for BIND_NOW however, as the linker might have that
# enabled by default. # enabled by default.
$(RUSTC) -Zrelro-level=off hello.rs $(RUSTC) -Crelro-level=off hello.rs
! readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO ! readelf -l $(TMPDIR)/hello | grep -q GNU_RELRO

View file

@ -1,4 +1,6 @@
//@ check-pass
// This shouldn't cause a stack overflow when rustdoc is run // This shouldn't cause a stack overflow when rustdoc is run
// https://github.com/rust-lang/rust/issues/56701
use std::ops::Deref; use std::ops::Deref;
use std::ops::DerefMut; use std::ops::DerefMut;

View file

@ -1,5 +1,6 @@
// Regression test for ICE #73061 // Regression test for ICE https://github.com/rust-lang/rust/issues/73061
//@ check-pass
//@ aux-build:issue-73061.rs //@ aux-build:issue-73061.rs
extern crate issue_73061; extern crate issue_73061;

View file

@ -1,3 +1,4 @@
// https://github.com/rust-lang/rust/issues/78673
#![crate_name = "issue_78673"] #![crate_name = "issue_78673"]
pub trait Something {} pub trait Something {}

View file

@ -1,4 +1,7 @@
// @has 'issue_76501/fn.bloop.html' '//pre' 'pub const fn bloop() -> i32' // https://github.com/rust-lang/rust/issues/76501
#![crate_name="foo"]
// @has 'foo/fn.bloop.html' '//pre' 'pub const fn bloop() -> i32'
/// A useless function that always returns 1. /// A useless function that always returns 1.
pub const fn bloop() -> i32 { pub const fn bloop() -> i32 {
1 1
@ -8,7 +11,7 @@ pub const fn bloop() -> i32 {
pub struct Struct {} pub struct Struct {}
impl Struct { impl Struct {
// @has 'issue_76501/struct.Struct.html' '//*[@class="method"]' \ // @has 'foo/struct.Struct.html' '//*[@class="method"]' \
// 'pub const fn blurp() -> i32' // 'pub const fn blurp() -> i32'
/// A useless function that always returns 1. /// A useless function that always returns 1.
pub const fn blurp() -> i32 { pub const fn blurp() -> i32 {

View file

@ -1,6 +1,9 @@
// https://github.com/rust-lang/rust/issues/79201
#![crate_name="foo"]
#![feature(doc_cfg)] #![feature(doc_cfg)]
// @has 'issue_79201/trait.Foo.html' // @has 'foo/trait.Foo.html'
// @count - '//*[@class="stab portability"]' 6 // @count - '//*[@class="stab portability"]' 6
// @matches - '//*[@class="stab portability"]' 'crate feature foo-root' // @matches - '//*[@class="stab portability"]' 'crate feature foo-root'
// @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod' // @matches - '//*[@class="stab portability"]' 'crate feature foo-public-mod'

View file

@ -1,8 +1,10 @@
//@ compile-flags: -Zunstable-options --document-private-items --document-hidden-items //@ compile-flags: -Zunstable-options --document-private-items --document-hidden-items
// https://github.com/rust-lang/rust/issues/67851
#![crate_name="foo"]
// @has issue_67851_both/struct.Hidden.html // @has foo/struct.Hidden.html
#[doc(hidden)] #[doc(hidden)]
pub struct Hidden; pub struct Hidden;
// @has issue_67851_both/struct.Private.html // @has foo/struct.Private.html
struct Private; struct Private;

View file

@ -0,0 +1,10 @@
//@ compile-flags: -Zunstable-options --document-hidden-items
// https://github.com/rust-lang/rust/issues/67851
#![crate_name="foo"]
// @has foo/struct.Hidden.html
#[doc(hidden)]
pub struct Hidden;
// @!has foo/struct.Private.html
struct Private;

View file

@ -0,0 +1,9 @@
// https://github.com/rust-lang/rust/issues/67851
#![crate_name="foo"]
// @!has foo/struct.Hidden.html
#[doc(hidden)]
pub struct Hidden;
// @!has foo/struct.Private.html
struct Private;

View file

@ -0,0 +1,10 @@
//@ compile-flags: --document-private-items
// https://github.com/rust-lang/rust/issues/67851
#![crate_name="foo"]
// @!has foo/struct.Hidden.html
#[doc(hidden)]
pub struct Hidden;
// @has foo/struct.Private.html
struct Private;

View file

@ -1,3 +1,6 @@
// https://github.com/rust-lang/rust/issues/74083
#![crate_name="foo"]
use std::ops::Deref; use std::ops::Deref;
pub struct Foo; pub struct Foo;
@ -6,7 +9,7 @@ impl Foo {
pub fn foo(&mut self) {} pub fn foo(&mut self) {}
} }
// @has issue_74083/struct.Bar.html // @has foo/struct.Bar.html
// @!has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo' // @!has - '//div[@class="sidebar-links"]/a[@href="#method.foo"]' 'foo'
pub struct Bar { pub struct Bar {
foo: Foo, foo: Foo,

View file

@ -2,6 +2,7 @@
//@ aux-build:real_gimli.rs //@ aux-build:real_gimli.rs
// Ensure unstably exported traits have their Implementors sections. // Ensure unstably exported traits have their Implementors sections.
// https://github.com/rust-lang/rust/issues/75588
#![crate_name = "foo"] #![crate_name = "foo"]
#![feature(extremely_unstable_foo)] #![feature(extremely_unstable_foo)]

View file

@ -1,4 +1,5 @@
//@ aux-build:issue-57180.rs //@ aux-build:issue-57180.rs
// https://github.com/rust-lang/rust/issues/57180
extern crate issue_57180; extern crate issue_57180;
use issue_57180::Trait; use issue_57180::Trait;

View file

@ -1,3 +1,5 @@
// https://github.com/rust-lang/rust/issues/72340
#![crate_name = "foo"] #![crate_name = "foo"]
pub struct Body; pub struct Body;

View file

@ -1,8 +0,0 @@
//@ compile-flags: -Zunstable-options --document-hidden-items
// @has issue_67851_hidden/struct.Hidden.html
#[doc(hidden)]
pub struct Hidden;
// @!has issue_67851_hidden/struct.Private.html
struct Private;

View file

@ -1,6 +0,0 @@
// @!has issue_67851_neither/struct.Hidden.html
#[doc(hidden)]
pub struct Hidden;
// @!has issue_67851_neither/struct.Private.html
struct Private;

View file

@ -1,8 +0,0 @@
//@ compile-flags: --document-private-items
// @!has issue_67851_private/struct.Hidden.html
#[doc(hidden)]
pub struct Hidden;
// @has issue_67851_private/struct.Private.html
struct Private;

View file

@ -1,4 +1,5 @@
// This code caused a panic in `pulldown-cmark` 0.4.1. // This code caused a panic in `pulldown-cmark` 0.4.1.
// https://github.com/rust-lang/rust/issues/60482
pub const BASIC_UNICODE: bool = true; pub const BASIC_UNICODE: bool = true;

View file

@ -1,3 +1,4 @@
// https://github.com/rust-lang/rust/issues/78701
#![crate_name = "foo"] #![crate_name = "foo"]
// This test ensures that if a blanket impl has the same ID as another impl, it'll // This test ensures that if a blanket impl has the same ID as another impl, it'll

View file

@ -1,3 +1,6 @@
// https://github.com/rust-lang/rust/issues/56822
#![crate_name="foo"]
struct Wrapper<T>(T); struct Wrapper<T>(T);
trait MyTrait { trait MyTrait {
@ -16,7 +19,7 @@ impl<'a, T> MyTrait for Inner<'a, T> {
type Output = &'a T; type Output = &'a T;
} }
// @has issue_56822/struct.Parser.html // @has foo/struct.Parser.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<'a> Send for Parser<'a>" // "impl<'a> Send for Parser<'a>"
pub struct Parser<'a> { pub struct Parser<'a> {

View file

@ -1,3 +1,6 @@
// https://github.com/rust-lang/rust/issues/60726
#![crate_name="foo"]
use std::marker::PhantomData; use std::marker::PhantomData;
pub struct True; pub struct True;
@ -25,7 +28,7 @@ where
I:InterfaceType<Send=True> I:InterfaceType<Send=True>
{} {}
// @has issue_60726/struct.IntoIter.html // @has foo/struct.IntoIter.html
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \
// "impl<T> !Send for IntoIter<T>" // "impl<T> !Send for IntoIter<T>"
// @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \ // @has - '//*[@id="synthetic-implementations-list"]//*[@class="impl"]//h3[@class="code-header"]' \

View file

@ -1,14 +1,16 @@
//@ aux-build:issue-61592.rs //@ aux-build:issue-61592.rs
// https://github.com/rust-lang/rust/issues/61592
#![crate_name="bar"]
extern crate foo; extern crate foo;
// @has issue_61592/index.html // @has bar/index.html
// @has - '//a[@href="#reexports"]' 'Re-exports' // @has - '//a[@href="#reexports"]' 'Re-exports'
// @has - '//code' 'pub use foo::FooTrait as _;' // @has - '//code' 'pub use foo::FooTrait as _;'
// @!has - '//a[@href="trait._.html"]' '' // @!has - '//a[@href="trait._.html"]' ''
pub use foo::FooTrait as _; pub use foo::FooTrait as _;
// @has issue_61592/index.html // @has bar/index.html
// @has - '//a[@href="#reexports"]' 'Re-exports' // @has - '//a[@href="#reexports"]' 'Re-exports'
// @has - '//code' 'pub use foo::FooStruct as _;' // @has - '//code' 'pub use foo::FooStruct as _;'
// @!has - '//a[@href="struct._.html"]' '' // @!has - '//a[@href="struct._.html"]' ''

View file

@ -1,6 +1,5 @@
fn server() -> impl { fn server() -> impl {
//~^ ERROR at least one trait must be specified //~^ ERROR at least one trait must be specified
//~| ERROR type annotations needed
().map2(|| "") ().map2(|| "")
} }

View file

@ -5,7 +5,7 @@ LL | fn server() -> impl {
| ^^^^ | ^^^^
error[E0412]: cannot find type `F` in this scope error[E0412]: cannot find type `F` in this scope
--> $DIR/issue-78720.rs:14:12 --> $DIR/issue-78720.rs:13:12
| |
LL | _func: F, LL | _func: F,
| ^ | ^
@ -22,14 +22,8 @@ help: you might be missing a type parameter
LL | struct Map2<Segment2, F> { LL | struct Map2<Segment2, F> {
| +++ | +++
error[E0282]: type annotations needed
--> $DIR/issue-78720.rs:1:16
|
LL | fn server() -> impl {
| ^^^^ cannot infer type
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-78720.rs:8:39 --> $DIR/issue-78720.rs:7:39
| |
LL | fn map2<F>(self, f: F) -> Map2<F> {} LL | fn map2<F>(self, f: F) -> Map2<F> {}
| ^^ expected `Map2<F>`, found `()` | ^^ expected `Map2<F>`, found `()`
@ -38,7 +32,7 @@ LL | fn map2<F>(self, f: F) -> Map2<F> {}
found unit type `()` found unit type `()`
error[E0277]: the size for values of type `Self` cannot be known at compilation time error[E0277]: the size for values of type `Self` cannot be known at compilation time
--> $DIR/issue-78720.rs:8:16 --> $DIR/issue-78720.rs:7:16
| |
LL | fn map2<F>(self, f: F) -> Map2<F> {} LL | fn map2<F>(self, f: F) -> Map2<F> {}
| ^^^^ doesn't have a size known at compile-time | ^^^^ doesn't have a size known at compile-time
@ -53,7 +47,7 @@ help: function arguments must have a statically known size, borrowed types alway
LL | fn map2<F>(&self, f: F) -> Map2<F> {} LL | fn map2<F>(&self, f: F) -> Map2<F> {}
| + | +
error: aborting due to 5 previous errors error: aborting due to 4 previous errors
Some errors have detailed explanations: E0277, E0282, E0308, E0412. Some errors have detailed explanations: E0277, E0308, E0412.
For more information about an error, try `rustc --explain E0277`. For more information about an error, try `rustc --explain E0277`.

View file

@ -13,7 +13,6 @@ impl Opcode2 {
pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) { pub fn example2(msg_type: Opcode2) -> impl FnMut(&[u8]) {
move |i| match msg_type { move |i| match msg_type {
Opcode2::OP2 => unimplemented!(), Opcode2::OP2 => unimplemented!(),
//~^ ERROR could not evaluate constant pattern
} }
} }

View file

@ -17,13 +17,7 @@ help: you might be missing a type parameter
LL | pub struct Opcode2<S>(&'a S); LL | pub struct Opcode2<S>(&'a S);
| +++ | +++
error: could not evaluate constant pattern error: aborting due to 2 previous errors
--> $DIR/ice-type-mismatch-when-copying-112824.rs:15:9
|
LL | Opcode2::OP2 => unimplemented!(),
| ^^^^^^^^^^^^
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0261, E0412. Some errors have detailed explanations: E0261, E0412.
For more information about an error, try `rustc --explain E0261`. For more information about an error, try `rustc --explain E0261`.

View file

@ -0,0 +1,15 @@
// Regression test for #123154
struct AA {
pub data: [&usize]
//~^ ERROR missing lifetime specifier
}
impl AA {
const fn new() -> Self { }
//~^ ERROR mismatched types
}
static ST: AA = AA::new();
fn main() {}

View file

@ -0,0 +1,24 @@
error[E0106]: missing lifetime specifier
--> $DIR/ice-unsized-struct-const-eval-123154.rs:4:16
|
LL | pub data: [&usize]
| ^ expected named lifetime parameter
|
help: consider introducing a named lifetime parameter
|
LL ~ struct AA<'a> {
LL ~ pub data: [&'a usize]
|
error[E0308]: mismatched types
--> $DIR/ice-unsized-struct-const-eval-123154.rs:9:23
|
LL | const fn new() -> Self { }
| --- ^^^^ expected `AA`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0106, E0308.
For more information about an error, try `rustc --explain E0106`.

View file

@ -17,6 +17,7 @@ impl<T, D> MyTrait<T> for D {
} }
impl<T> MyTrait<T> for BadStruct { impl<T> MyTrait<T> for BadStruct {
//~^ ERROR: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
fn foo() {} fn foo() {}
} }

View file

@ -4,6 +4,16 @@ error[E0412]: cannot find type `MissingType` in this scope
LL | err: MissingType LL | err: MissingType
| ^^^^^^^^^^^ not found in this scope | ^^^^^^^^^^^ not found in this scope
error: aborting due to 1 previous error error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `BadStruct`
--> $DIR/issue-68830-spurious-diagnostics.rs:19:1
|
LL | impl<T, D> MyTrait<T> for D {
| --------------------------- first implementation here
...
LL | impl<T> MyTrait<T> for BadStruct {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `BadStruct`
For more information about this error, try `rustc --explain E0412`. error: aborting due to 2 previous errors
Some errors have detailed explanations: E0119, E0412.
For more information about an error, try `rustc --explain E0119`.