Auto merge of #94514 - matthiaskrgr:rollup-pdzn82h, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #94464 (Suggest adding a new lifetime parameter when two elided lifetimes should match up for traits and impls.) - #94476 (7 - Make more use of `let_chains`) - #94478 (Fix panic when handling intra doc links generated from macro) - #94482 (compiler: fix some typos) - #94490 (Update books) - #94496 (tests: accept llvm intrinsic in align-checking test) - #94498 (9 - Make more use of `let_chains`) - #94503 (Provide C FFI types via core::ffi, not just in std) - #94513 (update Miri) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
2a280de64f
@ -1366,7 +1366,7 @@ pub(super) fn lower_generics_mut(
|
||||
generics: &Generics,
|
||||
itctx: ImplTraitContext<'_, 'hir>,
|
||||
) -> GenericsCtor<'hir> {
|
||||
// Error if `?Trait` bounds in where clauses don't refer directly to type paramters.
|
||||
// Error if `?Trait` bounds in where clauses don't refer directly to type parameters.
|
||||
// Note: we used to clone these bounds directly onto the type parameter (and avoid lowering
|
||||
// these into hir when we lower thee where clauses), but this makes it quite difficult to
|
||||
// keep track of the Span info. Now, `add_implicitly_sized` in `AstConv` checks both param bounds and
|
||||
|
@ -1992,7 +1992,7 @@ fn check_member_constraints(
|
||||
.find_map(|constraint| {
|
||||
if let ConstraintCategory::Predicate(predicate_span) = constraint.category {
|
||||
// We currentl'y doesn't store the `DefId` in the `ConstraintCategory`
|
||||
// for perforamnce reasons. The error reporting code used by NLL only
|
||||
// for performances reasons. The error reporting code used by NLL only
|
||||
// uses the span, so this doesn't cause any problems at the moment.
|
||||
Some(ObligationCauseCode::BindingObligation(
|
||||
CRATE_DEF_ID.to_def_id(),
|
||||
|
@ -201,7 +201,7 @@ fn configure_annotatable(&mut self, mut annotatable: Annotatable) -> Option<Anno
|
||||
|
||||
// Re-parse the tokens, setting the `capture_cfg` flag to save extra information
|
||||
// to the captured `AttrAnnotatedTokenStream` (specifically, we capture
|
||||
// `AttrAnnotatedTokenTree::AttributesData` for all occurences of `#[cfg]` and `#[cfg_attr]`)
|
||||
// `AttrAnnotatedTokenTree::AttributesData` for all occurrences of `#[cfg]` and `#[cfg_attr]`)
|
||||
let mut parser =
|
||||
rustc_parse::stream_to_parser(&self.cfg.sess.parse_sess, orig_tokens, None);
|
||||
parser.capture_cfg = true;
|
||||
|
@ -989,7 +989,7 @@ fn is_illegal_instruction(_status: &ExitStatus) -> bool {
|
||||
|
||||
// ... and otherwise we're processing a `*.dwp` packed dwarf file.
|
||||
//
|
||||
// We cannot rely on the .o paths in the exectuable because they may have been
|
||||
// We cannot rely on the .o paths in the executable because they may have been
|
||||
// remapped by --remap-path-prefix and therefore invalid, so we need to provide
|
||||
// the .o/.dwo paths explicitly.
|
||||
SplitDebuginfo::Packed => link_dwarf_object(sess, codegen_results, out_filename),
|
||||
|
@ -1338,7 +1338,7 @@ fn export_symbols(&mut self, _tmpdir: &Path, _crate_type: CrateType, symbols: &[
|
||||
}
|
||||
|
||||
// LLD will hide these otherwise-internal symbols since it only exports
|
||||
// symbols explicity passed via the `--export` flags above and hides all
|
||||
// symbols explicitly passed via the `--export` flags above and hides all
|
||||
// others. Various bits and pieces of tooling use this, so be sure these
|
||||
// symbols make their way out of the linker as well.
|
||||
self.cmd.arg("--export=__heap_base");
|
||||
|
@ -7,7 +7,7 @@
|
||||
/// one of two specific implementations.
|
||||
///
|
||||
/// Note: For most methods providing custom
|
||||
/// implementation may margianlly
|
||||
/// implementation may marginally
|
||||
/// improve performance by avoiding
|
||||
/// doing Left/Right match on every step
|
||||
/// and doing it only once instead.
|
||||
|
@ -50,7 +50,7 @@ fn allocate(&mut self, key: DefKey, def_path_hash: DefPathHash) -> DefIndex {
|
||||
// Continuing with colliding DefPathHashes can lead to correctness
|
||||
// issues. We must abort compilation.
|
||||
//
|
||||
// The likelyhood of such a collision is very small, so actually
|
||||
// The likelihood of such a collision is very small, so actually
|
||||
// running into one could be indicative of a poor hash function
|
||||
// being used.
|
||||
//
|
||||
|
@ -166,59 +166,61 @@ fn suggest_adding_lifetime_params(
|
||||
if lifetime_sub.name.is_elided() && lifetime_sup.name.is_elided() {
|
||||
if let Some(anon_reg) = self.tcx().is_suitable_region(sub) {
|
||||
let hir_id = self.tcx().hir().local_def_id_to_hir_id(anon_reg.def_id);
|
||||
if let hir::Node::Item(&hir::Item {
|
||||
kind: hir::ItemKind::Fn(_, ref generics, ..),
|
||||
..
|
||||
}) = self.tcx().hir().get(hir_id)
|
||||
{
|
||||
let (suggestion_param_name, introduce_new) = generics
|
||||
.params
|
||||
.iter()
|
||||
.find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
|
||||
.and_then(|p| self.tcx().sess.source_map().span_to_snippet(p.span).ok())
|
||||
.map(|name| (name, false))
|
||||
.unwrap_or_else(|| ("'a".to_string(), true));
|
||||
|
||||
let mut suggestions = vec![
|
||||
if let hir::LifetimeName::Underscore = lifetime_sub.name {
|
||||
(lifetime_sub.span, suggestion_param_name.clone())
|
||||
} else {
|
||||
(
|
||||
lifetime_sub.span.shrink_to_hi(),
|
||||
suggestion_param_name.clone() + " ",
|
||||
)
|
||||
},
|
||||
if let hir::LifetimeName::Underscore = lifetime_sup.name {
|
||||
(lifetime_sup.span, suggestion_param_name.clone())
|
||||
} else {
|
||||
(
|
||||
lifetime_sup.span.shrink_to_hi(),
|
||||
suggestion_param_name.clone() + " ",
|
||||
)
|
||||
},
|
||||
];
|
||||
let node = self.tcx().hir().get(hir_id);
|
||||
let is_impl = matches!(&node, hir::Node::ImplItem(_));
|
||||
let generics = match node {
|
||||
hir::Node::Item(&hir::Item {
|
||||
kind: hir::ItemKind::Fn(_, ref generics, ..),
|
||||
..
|
||||
})
|
||||
| hir::Node::TraitItem(&hir::TraitItem { ref generics, .. })
|
||||
| hir::Node::ImplItem(&hir::ImplItem { ref generics, .. }) => generics,
|
||||
_ => return,
|
||||
};
|
||||
|
||||
if introduce_new {
|
||||
let new_param_suggestion = match &generics.params {
|
||||
[] => (generics.span, format!("<{}>", suggestion_param_name)),
|
||||
[first, ..] => (
|
||||
first.span.shrink_to_lo(),
|
||||
format!("{}, ", suggestion_param_name),
|
||||
),
|
||||
};
|
||||
let (suggestion_param_name, introduce_new) = generics
|
||||
.params
|
||||
.iter()
|
||||
.find(|p| matches!(p.kind, GenericParamKind::Lifetime { .. }))
|
||||
.and_then(|p| self.tcx().sess.source_map().span_to_snippet(p.span).ok())
|
||||
.map(|name| (name, false))
|
||||
.unwrap_or_else(|| ("'a".to_string(), true));
|
||||
|
||||
suggestions.push(new_param_suggestion);
|
||||
}
|
||||
let mut suggestions = vec![
|
||||
if let hir::LifetimeName::Underscore = lifetime_sub.name {
|
||||
(lifetime_sub.span, suggestion_param_name.clone())
|
||||
} else {
|
||||
(lifetime_sub.span.shrink_to_hi(), suggestion_param_name.clone() + " ")
|
||||
},
|
||||
if let hir::LifetimeName::Underscore = lifetime_sup.name {
|
||||
(lifetime_sup.span, suggestion_param_name.clone())
|
||||
} else {
|
||||
(lifetime_sup.span.shrink_to_hi(), suggestion_param_name.clone() + " ")
|
||||
},
|
||||
];
|
||||
|
||||
err.multipart_suggestion(
|
||||
"consider introducing a named lifetime parameter",
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.note(
|
||||
"each elided lifetime in input position becomes a distinct lifetime",
|
||||
);
|
||||
if introduce_new {
|
||||
let new_param_suggestion = match &generics.params {
|
||||
[] => (generics.span, format!("<{}>", suggestion_param_name)),
|
||||
[first, ..] => {
|
||||
(first.span.shrink_to_lo(), format!("{}, ", suggestion_param_name))
|
||||
}
|
||||
};
|
||||
|
||||
suggestions.push(new_param_suggestion);
|
||||
}
|
||||
|
||||
let mut sugg = String::from("consider introducing a named lifetime parameter");
|
||||
if is_impl {
|
||||
sugg.push_str(" and update trait if needed");
|
||||
}
|
||||
err.multipart_suggestion(
|
||||
sugg.as_str(),
|
||||
suggestions,
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
err.note("each elided lifetime in input position becomes a distinct lifetime");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -55,10 +55,8 @@ fn find_optimization_oportunities<'tcx>(body: &Body<'tcx>) -> Vec<(Local, Consta
|
||||
|
||||
let mut locals_to_debuginfo = BitSet::new_empty(body.local_decls.len());
|
||||
for debuginfo in &body.var_debug_info {
|
||||
if let VarDebugInfoContents::Place(p) = debuginfo.value {
|
||||
if let Some(l) = p.as_local() {
|
||||
locals_to_debuginfo.insert(l);
|
||||
}
|
||||
if let VarDebugInfoContents::Place(p) = debuginfo.value && let Some(l) = p.as_local() {
|
||||
locals_to_debuginfo.insert(l);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -633,24 +633,22 @@ fn check_binary_op(
|
||||
fn propagate_operand(&mut self, operand: &mut Operand<'tcx>) {
|
||||
match *operand {
|
||||
Operand::Copy(l) | Operand::Move(l) => {
|
||||
if let Some(value) = self.get_const(l) {
|
||||
if self.should_const_prop(&value) {
|
||||
// FIXME(felix91gr): this code only handles `Scalar` cases.
|
||||
// For now, we're not handling `ScalarPair` cases because
|
||||
// doing so here would require a lot of code duplication.
|
||||
// We should hopefully generalize `Operand` handling into a fn,
|
||||
// and use it to do const-prop here and everywhere else
|
||||
// where it makes sense.
|
||||
if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
|
||||
ScalarMaybeUninit::Scalar(scalar),
|
||||
)) = *value
|
||||
{
|
||||
*operand = self.operand_from_scalar(
|
||||
scalar,
|
||||
value.layout.ty,
|
||||
self.source_info.unwrap().span,
|
||||
);
|
||||
}
|
||||
if let Some(value) = self.get_const(l) && self.should_const_prop(&value) {
|
||||
// FIXME(felix91gr): this code only handles `Scalar` cases.
|
||||
// For now, we're not handling `ScalarPair` cases because
|
||||
// doing so here would require a lot of code duplication.
|
||||
// We should hopefully generalize `Operand` handling into a fn,
|
||||
// and use it to do const-prop here and everywhere else
|
||||
// where it makes sense.
|
||||
if let interpret::Operand::Immediate(interpret::Immediate::Scalar(
|
||||
ScalarMaybeUninit::Scalar(scalar),
|
||||
)) = *value
|
||||
{
|
||||
*operand = self.operand_from_scalar(
|
||||
scalar,
|
||||
value.layout.ty,
|
||||
self.source_info.unwrap().span,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1086,15 +1084,13 @@ fn visit_statement(&mut self, statement: &mut Statement<'tcx>, location: Locatio
|
||||
// This will return None if the above `const_prop` invocation only "wrote" a
|
||||
// type whose creation requires no write. E.g. a generator whose initial state
|
||||
// consists solely of uninitialized memory (so it doesn't capture any locals).
|
||||
if let Some(ref value) = self.get_const(place) {
|
||||
if self.should_const_prop(value) {
|
||||
trace!("replacing {:?} with {:?}", rval, value);
|
||||
self.replace_with_const(rval, value, source_info);
|
||||
if can_const_prop == ConstPropMode::FullConstProp
|
||||
|| can_const_prop == ConstPropMode::OnlyInsideOwnBlock
|
||||
{
|
||||
trace!("propagated into {:?}", place);
|
||||
}
|
||||
if let Some(ref value) = self.get_const(place) && self.should_const_prop(value) {
|
||||
trace!("replacing {:?} with {:?}", rval, value);
|
||||
self.replace_with_const(rval, value, source_info);
|
||||
if can_const_prop == ConstPropMode::FullConstProp
|
||||
|| can_const_prop == ConstPropMode::OnlyInsideOwnBlock
|
||||
{
|
||||
trace!("propagated into {:?}", place);
|
||||
}
|
||||
}
|
||||
match can_const_prop {
|
||||
|
@ -357,14 +357,12 @@ fn format_operand(&self, operand: ExpressionOperandId) -> String {
|
||||
if let Some(counters) = &self.some_counters {
|
||||
if let Some(DebugCounter { counter_kind, some_block_label }) = counters.get(&operand) {
|
||||
if let CoverageKind::Expression { .. } = counter_kind {
|
||||
if let Some(block_label) = some_block_label {
|
||||
if debug_options().counter_format.block {
|
||||
return format!(
|
||||
"{}:({})",
|
||||
block_label,
|
||||
self.format_counter_kind(counter_kind)
|
||||
);
|
||||
}
|
||||
if let Some(label) = some_block_label && debug_options().counter_format.block {
|
||||
return format!(
|
||||
"{}:({})",
|
||||
label,
|
||||
self.format_counter_kind(counter_kind)
|
||||
);
|
||||
}
|
||||
return format!("({})", self.format_counter_kind(counter_kind));
|
||||
}
|
||||
|
@ -191,16 +191,13 @@ pub fn current_macro(&self) -> Option<Symbol> {
|
||||
/// If the span is part of a macro, and the macro is visible (expands directly to the given
|
||||
/// body_span), returns the macro name symbol.
|
||||
pub fn visible_macro(&self, body_span: Span) -> Option<Symbol> {
|
||||
if let Some(current_macro) = self.current_macro() {
|
||||
if self
|
||||
.expn_span
|
||||
.parent_callsite()
|
||||
.unwrap_or_else(|| bug!("macro must have a parent"))
|
||||
.ctxt()
|
||||
== body_span.ctxt()
|
||||
{
|
||||
return Some(current_macro);
|
||||
}
|
||||
if let Some(current_macro) = self.current_macro() && self
|
||||
.expn_span
|
||||
.parent_callsite()
|
||||
.unwrap_or_else(|| bug!("macro must have a parent"))
|
||||
.ctxt() == body_span.ctxt()
|
||||
{
|
||||
return Some(current_macro);
|
||||
}
|
||||
None
|
||||
}
|
||||
@ -584,21 +581,19 @@ fn take_prev(&mut self) -> CoverageSpan {
|
||||
/// In either case, no more spans will match the span of `pending_dups`, so
|
||||
/// add the `pending_dups` if they don't overlap `curr`, and clear the list.
|
||||
fn check_pending_dups(&mut self) {
|
||||
if let Some(dup) = self.pending_dups.last() {
|
||||
if dup.span != self.prev().span {
|
||||
debug!(
|
||||
" SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \
|
||||
previous iteration, or prev started a new disjoint span"
|
||||
);
|
||||
if dup.span.hi() <= self.curr().span.lo() {
|
||||
let pending_dups = self.pending_dups.split_off(0);
|
||||
for dup in pending_dups.into_iter() {
|
||||
debug!(" ...adding at least one pending={:?}", dup);
|
||||
self.push_refined_span(dup);
|
||||
}
|
||||
} else {
|
||||
self.pending_dups.clear();
|
||||
if let Some(dup) = self.pending_dups.last() && dup.span != self.prev().span {
|
||||
debug!(
|
||||
" SAME spans, but pending_dups are NOT THE SAME, so BCBs matched on \
|
||||
previous iteration, or prev started a new disjoint span"
|
||||
);
|
||||
if dup.span.hi() <= self.curr().span.lo() {
|
||||
let pending_dups = self.pending_dups.split_off(0);
|
||||
for dup in pending_dups.into_iter() {
|
||||
debug!(" ...adding at least one pending={:?}", dup);
|
||||
self.push_refined_span(dup);
|
||||
}
|
||||
} else {
|
||||
self.pending_dups.clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -549,14 +549,15 @@ fn record_terminator_conflicts(&mut self, term: &Terminator<'_>) {
|
||||
target: _,
|
||||
unwind: _,
|
||||
} => {
|
||||
if let Some(place) = value.place() {
|
||||
if !place.is_indirect() && !dropped_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dropped_place.local,
|
||||
"DropAndReplace operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(place) = value.place()
|
||||
&& !place.is_indirect()
|
||||
&& !dropped_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dropped_place.local,
|
||||
"DropAndReplace operand overlap",
|
||||
);
|
||||
}
|
||||
}
|
||||
TerminatorKind::Yield { value, resume: _, resume_arg, drop: _ } => {
|
||||
@ -614,14 +615,15 @@ fn record_terminator_conflicts(&mut self, term: &Terminator<'_>) {
|
||||
for op in operands {
|
||||
match op {
|
||||
InlineAsmOperand::In { reg: _, value } => {
|
||||
if let Some(p) = value.place() {
|
||||
if !p.is_indirect() && !dest_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
p.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(p) = value.place()
|
||||
&& !p.is_indirect()
|
||||
&& !dest_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
p.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Out {
|
||||
@ -643,24 +645,26 @@ fn record_terminator_conflicts(&mut self, term: &Terminator<'_>) {
|
||||
in_value,
|
||||
out_place,
|
||||
} => {
|
||||
if let Some(place) = in_value.place() {
|
||||
if !place.is_indirect() && !dest_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(place) = in_value.place()
|
||||
&& !place.is_indirect()
|
||||
&& !dest_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
|
||||
if let Some(place) = out_place {
|
||||
if !place.is_indirect() && !dest_place.is_indirect() {
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
if let Some(place) = out_place
|
||||
&& !place.is_indirect()
|
||||
&& !dest_place.is_indirect()
|
||||
{
|
||||
self.record_local_conflict(
|
||||
place.local,
|
||||
dest_place.local,
|
||||
"asm! operand overlap",
|
||||
);
|
||||
}
|
||||
}
|
||||
InlineAsmOperand::Out { reg: _, late: _, place: None }
|
||||
|
@ -724,12 +724,11 @@ fn create_temp_if_necessary(
|
||||
caller_body: &mut Body<'tcx>,
|
||||
) -> Local {
|
||||
// Reuse the operand if it is a moved temporary.
|
||||
if let Operand::Move(place) = &arg {
|
||||
if let Some(local) = place.as_local() {
|
||||
if caller_body.local_kind(local) == LocalKind::Temp {
|
||||
return local;
|
||||
}
|
||||
}
|
||||
if let Operand::Move(place) = &arg
|
||||
&& let Some(local) = place.as_local()
|
||||
&& caller_body.local_kind(local) == LocalKind::Temp
|
||||
{
|
||||
return local;
|
||||
}
|
||||
|
||||
// Otherwise, create a temporary for the argument.
|
||||
|
@ -77,10 +77,8 @@ fn combine_bool_cmp(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>)
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(new) = new {
|
||||
if self.should_combine(source_info, rvalue) {
|
||||
*rvalue = new;
|
||||
}
|
||||
if let Some(new) = new && self.should_combine(source_info, rvalue) {
|
||||
*rvalue = new;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +1,17 @@
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(map_try_insert)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(option_get_or_insert_default)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(never_type)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(option_get_or_insert_default)]
|
||||
#![feature(trusted_step)]
|
||||
#![feature(try_blocks)]
|
||||
#![recursion_limit = "256"]
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate tracing;
|
||||
|
@ -14,10 +14,9 @@ pub fn new(required_consts: &'a mut Vec<Constant<'tcx>>) -> Self {
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
|
||||
fn visit_constant(&mut self, constant: &Constant<'tcx>, _: Location) {
|
||||
if let Some(ct) = constant.literal.const_for_ty() {
|
||||
if let ConstKind::Unevaluated(_) = ct.val() {
|
||||
self.required_consts.push(*constant);
|
||||
}
|
||||
let literal = constant.literal;
|
||||
if let Some(ct) = literal.const_for_ty() && let ConstKind::Unevaluated(_) = ct.val() {
|
||||
self.required_consts.push(*constant);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,19 +10,20 @@
|
||||
//!
|
||||
//! This API is completely unstable and subject to change.
|
||||
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
|
||||
#![feature(bool_to_option)]
|
||||
#![feature(box_patterns)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(derive_default_enum)]
|
||||
#![feature(drain_filter)]
|
||||
#![feature(hash_drain_filter)]
|
||||
#![feature(label_break_value)]
|
||||
#![feature(let_chains)]
|
||||
#![feature(let_else)]
|
||||
#![feature(never_type)]
|
||||
#![feature(crate_visibility_modifier)]
|
||||
#![feature(control_flow_enum)]
|
||||
#![recursion_limit = "512"] // For rustdoc
|
||||
#![allow(rustc::potential_query_instability)]
|
||||
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
@ -1098,42 +1098,43 @@ fn report_arg_count_mismatch(
|
||||
);
|
||||
}
|
||||
}
|
||||
if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..] {
|
||||
if fields.len() == found_args.len() && is_closure {
|
||||
let sugg = format!(
|
||||
"|({}){}|",
|
||||
found_args
|
||||
.iter()
|
||||
.map(|arg| match arg {
|
||||
ArgKind::Arg(name, _) => name.to_owned(),
|
||||
_ => "_".to_owned(),
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(", "),
|
||||
// add type annotations if available
|
||||
if found_args.iter().any(|arg| match arg {
|
||||
ArgKind::Arg(_, ty) => ty != "_",
|
||||
_ => false,
|
||||
}) {
|
||||
format!(
|
||||
": ({})",
|
||||
fields
|
||||
.iter()
|
||||
.map(|(_, ty)| ty.to_owned())
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
);
|
||||
err.span_suggestion_verbose(
|
||||
found_span,
|
||||
"change the closure to accept a tuple instead of individual arguments",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
if let &[ArgKind::Tuple(_, ref fields)] = &expected_args[..]
|
||||
&& fields.len() == found_args.len()
|
||||
&& is_closure
|
||||
{
|
||||
let sugg = format!(
|
||||
"|({}){}|",
|
||||
found_args
|
||||
.iter()
|
||||
.map(|arg| match arg {
|
||||
ArgKind::Arg(name, _) => name.to_owned(),
|
||||
_ => "_".to_owned(),
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(", "),
|
||||
// add type annotations if available
|
||||
if found_args.iter().any(|arg| match arg {
|
||||
ArgKind::Arg(_, ty) => ty != "_",
|
||||
_ => false,
|
||||
}) {
|
||||
format!(
|
||||
": ({})",
|
||||
fields
|
||||
.iter()
|
||||
.map(|(_, ty)| ty.to_owned())
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
);
|
||||
err.span_suggestion_verbose(
|
||||
found_span,
|
||||
"change the closure to accept a tuple instead of individual arguments",
|
||||
sugg,
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2231,16 +2232,13 @@ fn is_recursive_obligation(
|
||||
if obligated_types.iter().any(|ot| ot == &self_ty) {
|
||||
return true;
|
||||
}
|
||||
if let ty::Adt(def, substs) = self_ty.kind() {
|
||||
if let [arg] = &substs[..] {
|
||||
if let ty::subst::GenericArgKind::Type(ty) = arg.unpack() {
|
||||
if let ty::Adt(inner_def, _) = ty.kind() {
|
||||
if inner_def == def {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let ty::Adt(def, substs) = self_ty.kind()
|
||||
&& let [arg] = &substs[..]
|
||||
&& let ty::subst::GenericArgKind::Type(ty) = arg.unpack()
|
||||
&& let ty::Adt(inner_def, _) = ty.kind()
|
||||
&& inner_def == def
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
|
@ -891,23 +891,20 @@ fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut
|
||||
}
|
||||
if let Some(typeck_results) =
|
||||
self.in_progress_typeck_results.map(|t| t.borrow())
|
||||
&& let ty = typeck_results.expr_ty_adjusted(base)
|
||||
&& let ty::FnDef(def_id, _substs) = ty.kind()
|
||||
&& let Some(hir::Node::Item(hir::Item { span, ident, .. })) =
|
||||
hir.get_if_local(*def_id)
|
||||
{
|
||||
let ty = typeck_results.expr_ty_adjusted(base);
|
||||
if let ty::FnDef(def_id, _substs) = ty.kind() {
|
||||
if let Some(hir::Node::Item(hir::Item { span, ident, .. })) =
|
||||
hir.get_if_local(*def_id)
|
||||
{
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
&format!(
|
||||
"alternatively, consider making `fn {}` asynchronous",
|
||||
ident
|
||||
),
|
||||
"async ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
err.span_suggestion_verbose(
|
||||
span.shrink_to_lo(),
|
||||
&format!(
|
||||
"alternatively, consider making `fn {}` asynchronous",
|
||||
ident
|
||||
),
|
||||
"async ".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1000,34 +997,24 @@ fn suggest_semicolon_removal(
|
||||
span: Span,
|
||||
trait_pred: ty::PolyTraitPredicate<'tcx>,
|
||||
) {
|
||||
let is_empty_tuple =
|
||||
|ty: ty::Binder<'tcx, Ty<'_>>| *ty.skip_binder().kind() == ty::Tuple(ty::List::empty());
|
||||
|
||||
let hir = self.tcx.hir();
|
||||
let parent_node = hir.get_parent_node(obligation.cause.body_id);
|
||||
let node = hir.find(parent_node);
|
||||
if let Some(hir::Node::Item(hir::Item {
|
||||
kind: hir::ItemKind::Fn(sig, _, body_id), ..
|
||||
})) = node
|
||||
if let Some(hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. })) = node
|
||||
&& let body = hir.body(*body_id)
|
||||
&& let hir::ExprKind::Block(blk, _) = &body.value.kind
|
||||
&& sig.decl.output.span().overlaps(span)
|
||||
&& blk.expr.is_none()
|
||||
&& *trait_pred.self_ty().skip_binder().kind() == ty::Tuple(ty::List::empty())
|
||||
// FIXME(estebank): When encountering a method with a trait
|
||||
// bound not satisfied in the return type with a body that has
|
||||
// no return, suggest removal of semicolon on last statement.
|
||||
// Once that is added, close #54771.
|
||||
&& let Some(stmt) = blk.stmts.last()
|
||||
&& let hir::StmtKind::Semi(_) = stmt.kind
|
||||
{
|
||||
let body = hir.body(*body_id);
|
||||
if let hir::ExprKind::Block(blk, _) = &body.value.kind {
|
||||
if sig.decl.output.span().overlaps(span)
|
||||
&& blk.expr.is_none()
|
||||
&& is_empty_tuple(trait_pred.self_ty())
|
||||
{
|
||||
// FIXME(estebank): When encountering a method with a trait
|
||||
// bound not satisfied in the return type with a body that has
|
||||
// no return, suggest removal of semicolon on last statement.
|
||||
// Once that is added, close #54771.
|
||||
if let Some(ref stmt) = blk.stmts.last() {
|
||||
if let hir::StmtKind::Semi(_) = stmt.kind {
|
||||
let sp = self.tcx.sess.source_map().end_point(stmt.span);
|
||||
err.span_label(sp, "consider removing this semicolon");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let sp = self.tcx.sess.source_map().end_point(stmt.span);
|
||||
err.span_label(sp, "consider removing this semicolon");
|
||||
}
|
||||
}
|
||||
|
||||
@ -2481,17 +2468,15 @@ fn suggest_await_before_try(
|
||||
debug!("suggest_await_before_try: try_trait_obligation {:?}", try_obligation);
|
||||
if self.predicate_may_hold(&try_obligation)
|
||||
&& impls_future.must_apply_modulo_regions()
|
||||
&& let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
|
||||
&& snippet.ends_with('?')
|
||||
{
|
||||
if let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span) {
|
||||
if snippet.ends_with('?') {
|
||||
err.span_suggestion_verbose(
|
||||
span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(),
|
||||
"consider `await`ing on the `Future`",
|
||||
".await".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
err.span_suggestion_verbose(
|
||||
span.with_hi(span.hi() - BytePos(1)).shrink_to_hi(),
|
||||
"consider `await`ing on the `Future`",
|
||||
".await".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,10 +91,8 @@ fn parse(
|
||||
)
|
||||
})?;
|
||||
attr::eval_condition(cond, &tcx.sess.parse_sess, Some(tcx.features()), &mut |item| {
|
||||
if let Some(symbol) = item.value_str() {
|
||||
if parse_value(symbol).is_err() {
|
||||
errored = true;
|
||||
}
|
||||
if let Some(symbol) = item.value_str() && parse_value(symbol).is_err() {
|
||||
errored = true;
|
||||
}
|
||||
true
|
||||
});
|
||||
@ -232,24 +230,22 @@ pub fn evaluate(
|
||||
options.iter().filter_map(|(k, v)| v.as_ref().map(|v| (*k, v.to_owned()))).collect();
|
||||
|
||||
for command in self.subcommands.iter().chain(Some(self)).rev() {
|
||||
if let Some(ref condition) = command.condition {
|
||||
if !attr::eval_condition(
|
||||
condition,
|
||||
&tcx.sess.parse_sess,
|
||||
Some(tcx.features()),
|
||||
&mut |c| {
|
||||
c.ident().map_or(false, |ident| {
|
||||
let value = c.value_str().map(|s| {
|
||||
OnUnimplementedFormatString(s).format(tcx, trait_ref, &options_map)
|
||||
});
|
||||
if let Some(ref condition) = command.condition && !attr::eval_condition(
|
||||
condition,
|
||||
&tcx.sess.parse_sess,
|
||||
Some(tcx.features()),
|
||||
&mut |c| {
|
||||
c.ident().map_or(false, |ident| {
|
||||
let value = c.value_str().map(|s| {
|
||||
OnUnimplementedFormatString(s).format(tcx, trait_ref, &options_map)
|
||||
});
|
||||
|
||||
options.contains(&(ident.name, value))
|
||||
})
|
||||
},
|
||||
) {
|
||||
debug!("evaluate: skipping {:?} due to condition", command);
|
||||
continue;
|
||||
}
|
||||
options.contains(&(ident.name, value))
|
||||
})
|
||||
},
|
||||
) {
|
||||
debug!("evaluate: skipping {:?} due to condition", command);
|
||||
continue;
|
||||
}
|
||||
debug!("evaluate: {:?} succeeded", command);
|
||||
if let Some(ref message_) = command.message {
|
||||
|
@ -43,21 +43,19 @@ fn dropck_outlives(&self, ty: Ty<'tcx>) -> InferOk<'tcx, Vec<GenericArg<'tcx>>>
|
||||
let c_ty = self.infcx.canonicalize_query(self.param_env.and(ty), &mut orig_values);
|
||||
let span = self.cause.span;
|
||||
debug!("c_ty = {:?}", c_ty);
|
||||
if let Ok(result) = tcx.dropck_outlives(c_ty) {
|
||||
if result.is_proven() {
|
||||
if let Ok(InferOk { value, obligations }) =
|
||||
self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
result,
|
||||
)
|
||||
{
|
||||
let ty = self.infcx.resolve_vars_if_possible(ty);
|
||||
let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
|
||||
return InferOk { value: kinds, obligations };
|
||||
}
|
||||
}
|
||||
if let Ok(result) = tcx.dropck_outlives(c_ty)
|
||||
&& result.is_proven()
|
||||
&& let Ok(InferOk { value, obligations }) =
|
||||
self.infcx.instantiate_query_response_and_region_obligations(
|
||||
self.cause,
|
||||
self.param_env,
|
||||
&orig_values,
|
||||
result,
|
||||
)
|
||||
{
|
||||
let ty = self.infcx.resolve_vars_if_possible(ty);
|
||||
let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
|
||||
return InferOk { value: kinds, obligations };
|
||||
}
|
||||
|
||||
// Errors and ambiuity in dropck occur in two cases:
|
||||
|
@ -12,50 +12,38 @@ pub(crate) fn update<'tcx, T>(
|
||||
T: TraitEngine<'tcx>,
|
||||
{
|
||||
// (*) binder skipped
|
||||
if let ty::PredicateKind::Trait(predicate) = obligation.predicate.kind().skip_binder() {
|
||||
if let Some(ty) =
|
||||
infcx.shallow_resolve(predicate.self_ty()).ty_vid().map(|t| infcx.root_var(t))
|
||||
{
|
||||
if infcx
|
||||
.tcx
|
||||
.lang_items()
|
||||
.sized_trait()
|
||||
.map_or(false, |st| st != predicate.trait_ref.def_id)
|
||||
{
|
||||
let new_self_ty = infcx.tcx.types.unit;
|
||||
if let ty::PredicateKind::Trait(tpred) = obligation.predicate.kind().skip_binder()
|
||||
&& let Some(ty) = infcx.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| infcx.root_var(t))
|
||||
&& infcx.tcx.lang_items().sized_trait().map_or(false, |st| st != tpred.trait_ref.def_id)
|
||||
{
|
||||
let new_self_ty = infcx.tcx.types.unit;
|
||||
|
||||
let trait_ref = ty::TraitRef {
|
||||
substs: infcx
|
||||
.tcx
|
||||
.mk_substs_trait(new_self_ty, &predicate.trait_ref.substs[1..]),
|
||||
..predicate.trait_ref
|
||||
};
|
||||
let trait_ref = ty::TraitRef {
|
||||
substs: infcx.tcx.mk_substs_trait(new_self_ty, &tpred.trait_ref.substs[1..]),
|
||||
..tpred.trait_ref
|
||||
};
|
||||
|
||||
// Then contstruct a new obligation with Self = () added
|
||||
// to the ParamEnv, and see if it holds.
|
||||
let o = rustc_infer::traits::Obligation::new(
|
||||
ObligationCause::dummy(),
|
||||
obligation.param_env,
|
||||
obligation
|
||||
.predicate
|
||||
.kind()
|
||||
.map_bound(|_| {
|
||||
// (*) binder moved here
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: predicate.constness,
|
||||
polarity: predicate.polarity,
|
||||
})
|
||||
})
|
||||
.to_predicate(infcx.tcx),
|
||||
);
|
||||
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
||||
if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) {
|
||||
if result.may_apply() {
|
||||
engine.relationships().entry(ty).or_default().self_in_trait = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Then contstruct a new obligation with Self = () added
|
||||
// to the ParamEnv, and see if it holds.
|
||||
let o = rustc_infer::traits::Obligation::new(
|
||||
ObligationCause::dummy(),
|
||||
obligation.param_env,
|
||||
obligation
|
||||
.predicate
|
||||
.kind()
|
||||
.map_bound(|_| {
|
||||
// (*) binder moved here
|
||||
ty::PredicateKind::Trait(ty::TraitPredicate {
|
||||
trait_ref,
|
||||
constness: tpred.constness,
|
||||
polarity: tpred.polarity,
|
||||
})
|
||||
})
|
||||
.to_predicate(infcx.tcx),
|
||||
);
|
||||
// Don't report overflow errors. Otherwise equivalent to may_hold.
|
||||
if let Ok(result) = infcx.probe(|_| infcx.evaluate_obligation(&o)) && result.may_apply() {
|
||||
engine.relationships().entry(ty).or_default().self_in_trait = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -579,24 +579,22 @@ fn evaluate_predicate_recursively<'o>(
|
||||
previous_stack,
|
||||
subobligations,
|
||||
);
|
||||
if let Ok(res) = res {
|
||||
if res == EvaluatedToOk || res == EvaluatedToOkModuloRegions {
|
||||
if let Some(key) =
|
||||
ProjectionCacheKey::from_poly_projection_predicate(
|
||||
self, data,
|
||||
)
|
||||
{
|
||||
// If the result is something that we can cache, then mark this
|
||||
// entry as 'complete'. This will allow us to skip evaluating the
|
||||
// suboligations at all the next time we evaluate the projection
|
||||
// predicate.
|
||||
self.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.projection_cache()
|
||||
.complete(key, res);
|
||||
}
|
||||
}
|
||||
if let Ok(eval_rslt) = res
|
||||
&& (eval_rslt == EvaluatedToOk || eval_rslt == EvaluatedToOkModuloRegions)
|
||||
&& let Some(key) =
|
||||
ProjectionCacheKey::from_poly_projection_predicate(
|
||||
self, data,
|
||||
)
|
||||
{
|
||||
// If the result is something that we can cache, then mark this
|
||||
// entry as 'complete'. This will allow us to skip evaluating the
|
||||
// suboligations at all the next time we evaluate the projection
|
||||
// predicate.
|
||||
self.infcx
|
||||
.inner
|
||||
.borrow_mut()
|
||||
.projection_cache()
|
||||
.complete(key, eval_rslt);
|
||||
}
|
||||
res
|
||||
}
|
||||
|
@ -224,36 +224,30 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
|
||||
// projection coming from another associated type. See
|
||||
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
|
||||
// `traits-assoc-type-in-supertrait-bad.rs`.
|
||||
if let Some(ty::Projection(projection_ty)) = proj.term.ty().map(|ty| ty.kind()) {
|
||||
if let Some(&impl_item_id) =
|
||||
if let Some(ty::Projection(projection_ty)) = proj.term.ty().map(|ty| ty.kind())
|
||||
&& let Some(&impl_item_id) =
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
|
||||
{
|
||||
if let Some(impl_item_span) = items
|
||||
.iter()
|
||||
.find(|item| item.id.def_id.to_def_id() == impl_item_id)
|
||||
.map(fix_span)
|
||||
{
|
||||
cause.span = impl_item_span;
|
||||
}
|
||||
}
|
||||
&& let Some(impl_item_span) = items
|
||||
.iter()
|
||||
.find(|item| item.id.def_id.to_def_id() == impl_item_id)
|
||||
.map(fix_span)
|
||||
{
|
||||
cause.span = impl_item_span;
|
||||
}
|
||||
}
|
||||
ty::PredicateKind::Trait(pred) => {
|
||||
// An associated item obligation born out of the `trait` failed to be met. An example
|
||||
// can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
|
||||
debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
|
||||
if let ty::Projection(ty::ProjectionTy { item_def_id, .. }) = *pred.self_ty().kind() {
|
||||
if let Some(&impl_item_id) =
|
||||
if let ty::Projection(ty::ProjectionTy { item_def_id, .. }) = *pred.self_ty().kind()
|
||||
&& let Some(&impl_item_id) =
|
||||
tcx.impl_item_implementor_ids(impl_def_id).get(&item_def_id)
|
||||
{
|
||||
if let Some(impl_item_span) = items
|
||||
.iter()
|
||||
.find(|item| item.id.def_id.to_def_id() == impl_item_id)
|
||||
.map(fix_span)
|
||||
{
|
||||
cause.span = impl_item_span;
|
||||
}
|
||||
}
|
||||
&& let Some(impl_item_span) = items
|
||||
.iter()
|
||||
.find(|item| item.id.def_id.to_def_id() == impl_item_id)
|
||||
.map(fix_span)
|
||||
{
|
||||
cause.span = impl_item_span;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -2,8 +2,7 @@ Equivalent to C's `char` type.
|
||||
|
||||
[C's `char` type] is completely unlike [Rust's `char` type]; while Rust's type represents a unicode scalar value, C's `char` type is just an ordinary integer. On modern architectures this type will always be either [`i8`] or [`u8`], as they use byte-addresses memory with 8-bit bytes.
|
||||
|
||||
C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See [`CStr`] for more information.
|
||||
C chars are most commonly used to make C strings. Unlike Rust, where the length of a string is included alongside the string, C strings mark the end of a string with the character `'\0'`. See `CStr` for more information.
|
||||
|
||||
[C's `char` type]: https://en.wikipedia.org/wiki/C_data_types#Basic_types
|
||||
[Rust's `char` type]: char
|
||||
[`CStr`]: crate::ffi::CStr
|
16
library/core/src/ffi/c_void.md
Normal file
16
library/core/src/ffi/c_void.md
Normal file
@ -0,0 +1,16 @@
|
||||
Equivalent to C's `void` type when used as a [pointer].
|
||||
|
||||
In essence, `*const c_void` is equivalent to C's `const void*`
|
||||
and `*mut c_void` is equivalent to C's `void*`. That said, this is
|
||||
*not* the same as C's `void` return type, which is Rust's `()` type.
|
||||
|
||||
To model pointers to opaque types in FFI, until `extern type` is
|
||||
stabilized, it is recommended to use a newtype wrapper around an empty
|
||||
byte array. See the [Nomicon] for details.
|
||||
|
||||
One could use `std::os::raw::c_void` if they want to support old Rust
|
||||
compiler down to 1.1.0. After Rust 1.30.0, it was re-exported by
|
||||
this definition. For more information, please read [RFC 2521].
|
||||
|
||||
[Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
|
||||
[RFC 2521]: https://github.com/rust-lang/rfcs/blob/master/text/2521-c_void-reunification.md
|
@ -1,28 +1,157 @@
|
||||
//! Platform-specific types, as defined by C.
|
||||
//!
|
||||
//! Code that interacts via FFI will almost certainly be using the
|
||||
//! base types provided by C, which aren't nearly as nicely defined
|
||||
//! as Rust's primitive types. This module provides types which will
|
||||
//! match those defined by C, so that code that interacts with C will
|
||||
//! refer to the correct types.
|
||||
|
||||
#![stable(feature = "", since = "1.30.0")]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
//! Utilities related to foreign function interface (FFI) bindings.
|
||||
|
||||
use crate::fmt;
|
||||
use crate::marker::PhantomData;
|
||||
use crate::num::*;
|
||||
use crate::ops::{Deref, DerefMut};
|
||||
|
||||
/// Equivalent to C's `void` type when used as a [pointer].
|
||||
macro_rules! type_alias_no_nz {
|
||||
{
|
||||
$Docfile:tt, $Alias:ident = $Real:ty;
|
||||
$( $Cfg:tt )*
|
||||
} => {
|
||||
#[doc = include_str!($Docfile)]
|
||||
$( $Cfg )*
|
||||
#[unstable(feature = "core_ffi_c", issue = "94501")]
|
||||
pub type $Alias = $Real;
|
||||
}
|
||||
}
|
||||
|
||||
// To verify that the NonZero types in this file's macro invocations correspond
|
||||
//
|
||||
// perl -n < library/std/src/os/raw/mod.rs -e 'next unless m/type_alias\!/; die "$_ ?" unless m/, (c_\w+) = (\w+), NonZero_(\w+) = NonZero(\w+)/; die "$_ ?" unless $3 eq $1 and $4 eq ucfirst $2'
|
||||
//
|
||||
// NB this does not check that the main c_* types are right.
|
||||
|
||||
macro_rules! type_alias {
|
||||
{
|
||||
$Docfile:tt, $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty;
|
||||
$( $Cfg:tt )*
|
||||
} => {
|
||||
type_alias_no_nz! { $Docfile, $Alias = $Real; $( $Cfg )* }
|
||||
|
||||
#[doc = concat!("Type alias for `NonZero` version of [`", stringify!($Alias), "`]")]
|
||||
#[unstable(feature = "raw_os_nonzero", issue = "82363")]
|
||||
$( $Cfg )*
|
||||
pub type $NZAlias = $NZReal;
|
||||
}
|
||||
}
|
||||
|
||||
type_alias! { "c_char.md", c_char = c_char_definition::c_char, NonZero_c_char = c_char_definition::NonZero_c_char;
|
||||
// Make this type alias appear cfg-dependent so that Clippy does not suggest
|
||||
// replacing `0 as c_char` with `0_i8`/`0_u8`. This #[cfg(all())] can be removed
|
||||
// after the false positive in https://github.com/rust-lang/rust-clippy/issues/8093
|
||||
// is fixed.
|
||||
#[cfg(all())]
|
||||
#[doc(cfg(all()))] }
|
||||
type_alias! { "c_schar.md", c_schar = i8, NonZero_c_schar = NonZeroI8; }
|
||||
type_alias! { "c_uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; }
|
||||
type_alias! { "c_short.md", c_short = i16, NonZero_c_short = NonZeroI16; }
|
||||
type_alias! { "c_ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
|
||||
type_alias! { "c_int.md", c_int = i32, NonZero_c_int = NonZeroI32; }
|
||||
type_alias! { "c_uint.md", c_uint = u32, NonZero_c_uint = NonZeroU32; }
|
||||
type_alias! { "c_long.md", c_long = i32, NonZero_c_long = NonZeroI32;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(any(target_pointer_width = "32", windows))] }
|
||||
type_alias! { "c_ulong.md", c_ulong = u32, NonZero_c_ulong = NonZeroU32;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(any(target_pointer_width = "32", windows))] }
|
||||
type_alias! { "c_long.md", c_long = i64, NonZero_c_long = NonZeroI64;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(all(target_pointer_width = "64", not(windows)))] }
|
||||
type_alias! { "c_ulong.md", c_ulong = u64, NonZero_c_ulong = NonZeroU64;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(all(target_pointer_width = "64", not(windows)))] }
|
||||
type_alias! { "c_longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
|
||||
type_alias! { "c_ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
|
||||
type_alias_no_nz! { "c_float.md", c_float = f32; }
|
||||
type_alias_no_nz! { "c_double.md", c_double = f64; }
|
||||
|
||||
/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
|
||||
///
|
||||
/// In essence, `*const c_void` is equivalent to C's `const void*`
|
||||
/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
|
||||
/// *not* the same as C's `void` return type, which is Rust's `()` type.
|
||||
/// This type is currently always [`usize`], however in the future there may be
|
||||
/// platforms where this is not the case.
|
||||
#[unstable(feature = "c_size_t", issue = "88345")]
|
||||
pub type c_size_t = usize;
|
||||
|
||||
/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
|
||||
///
|
||||
/// To model pointers to opaque types in FFI, until `extern type` is
|
||||
/// stabilized, it is recommended to use a newtype wrapper around an empty
|
||||
/// byte array. See the [Nomicon] for details.
|
||||
/// This type is currently always [`isize`], however in the future there may be
|
||||
/// platforms where this is not the case.
|
||||
#[unstable(feature = "c_size_t", issue = "88345")]
|
||||
pub type c_ptrdiff_t = isize;
|
||||
|
||||
/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
|
||||
///
|
||||
/// One could use `std::os::raw::c_void` if they want to support old Rust
|
||||
/// compiler down to 1.1.0. After Rust 1.30.0, it was re-exported by
|
||||
/// this definition. For more information, please read [RFC 2521].
|
||||
///
|
||||
/// [Nomicon]: https://doc.rust-lang.org/nomicon/ffi.html#representing-opaque-structs
|
||||
/// [RFC 2521]: https://github.com/rust-lang/rfcs/blob/master/text/2521-c_void-reunification.md
|
||||
/// This type is currently always [`isize`], however in the future there may be
|
||||
/// platforms where this is not the case.
|
||||
#[unstable(feature = "c_size_t", issue = "88345")]
|
||||
pub type c_ssize_t = isize;
|
||||
|
||||
mod c_char_definition {
|
||||
cfg_if! {
|
||||
// These are the targets on which c_char is unsigned.
|
||||
if #[cfg(any(
|
||||
all(
|
||||
target_os = "linux",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "hexagon",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "s390x",
|
||||
target_arch = "riscv64",
|
||||
target_arch = "riscv32"
|
||||
)
|
||||
),
|
||||
all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
|
||||
all(target_os = "l4re", target_arch = "x86_64"),
|
||||
all(
|
||||
target_os = "freebsd",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "riscv64"
|
||||
)
|
||||
),
|
||||
all(
|
||||
target_os = "netbsd",
|
||||
any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc")
|
||||
),
|
||||
all(target_os = "openbsd", target_arch = "aarch64"),
|
||||
all(
|
||||
target_os = "vxworks",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "powerpc"
|
||||
)
|
||||
),
|
||||
all(target_os = "fuchsia", target_arch = "aarch64")
|
||||
))] {
|
||||
pub type c_char = u8;
|
||||
pub type NonZero_c_char = crate::num::NonZeroU8;
|
||||
} else {
|
||||
// On every other target, c_char is signed.
|
||||
pub type c_char = i8;
|
||||
pub type NonZero_c_char = crate::num::NonZeroI8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// N.B., for LLVM to recognize the void pointer type and by extension
|
||||
// functions like malloc(), we need to have it represented as i8* in
|
||||
// LLVM bitcode. The enum used here ensures this and prevents misuse
|
||||
@ -31,6 +160,7 @@
|
||||
// otherwise and we need at least one variant as otherwise the enum
|
||||
// would be uninhabited and at least dereferencing such pointers would
|
||||
// be UB.
|
||||
#[doc = include_str!("c_void.md")]
|
||||
#[repr(u8)]
|
||||
#[stable(feature = "core_c_void", since = "1.30.0")]
|
||||
pub enum c_void {
|
@ -187,3 +187,96 @@ extern "rust-call" fn call_once(self, ($( $arg, )*): ($( $ArgTy, )*)) -> $Return
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
/// A macro for defining `#[cfg]` if-else statements.
|
||||
///
|
||||
/// `cfg_if` is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade
|
||||
/// of `#[cfg]` cases, emitting the implementation which matches first.
|
||||
///
|
||||
/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code without having to
|
||||
/// rewrite each clause multiple times.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// cfg_if! {
|
||||
/// if #[cfg(unix)] {
|
||||
/// fn foo() { /* unix specific functionality */ }
|
||||
/// } else if #[cfg(target_pointer_width = "32")] {
|
||||
/// fn foo() { /* non-unix, 32-bit functionality */ }
|
||||
/// } else {
|
||||
/// fn foo() { /* fallback implementation */ }
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// # fn main() {}
|
||||
/// ```
|
||||
// This is a copy of `cfg_if!` from the `cfg_if` crate.
|
||||
// The recursive invocations should use $crate if this is ever exported.
|
||||
macro_rules! cfg_if {
|
||||
// match if/else chains with a final `else`
|
||||
(
|
||||
$(
|
||||
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
|
||||
) else+
|
||||
else { $( $e_tokens:tt )* }
|
||||
) => {
|
||||
cfg_if! {
|
||||
@__items () ;
|
||||
$(
|
||||
(( $i_meta ) ( $( $i_tokens )* )) ,
|
||||
)+
|
||||
(() ( $( $e_tokens )* )) ,
|
||||
}
|
||||
};
|
||||
|
||||
// match if/else chains lacking a final `else`
|
||||
(
|
||||
if #[cfg( $i_meta:meta )] { $( $i_tokens:tt )* }
|
||||
$(
|
||||
else if #[cfg( $e_meta:meta )] { $( $e_tokens:tt )* }
|
||||
)*
|
||||
) => {
|
||||
cfg_if! {
|
||||
@__items () ;
|
||||
(( $i_meta ) ( $( $i_tokens )* )) ,
|
||||
$(
|
||||
(( $e_meta ) ( $( $e_tokens )* )) ,
|
||||
)*
|
||||
}
|
||||
};
|
||||
|
||||
// Internal and recursive macro to emit all the items
|
||||
//
|
||||
// Collects all the previous cfgs in a list at the beginning, so they can be
|
||||
// negated. After the semicolon is all the remaining items.
|
||||
(@__items ( $( $_:meta , )* ) ; ) => {};
|
||||
(
|
||||
@__items ( $( $no:meta , )* ) ;
|
||||
(( $( $yes:meta )? ) ( $( $tokens:tt )* )) ,
|
||||
$( $rest:tt , )*
|
||||
) => {
|
||||
// Emit all items within one block, applying an appropriate #[cfg]. The
|
||||
// #[cfg] will require all `$yes` matchers specified and must also negate
|
||||
// all previous matchers.
|
||||
#[cfg(all(
|
||||
$( $yes , )?
|
||||
not(any( $( $no ),* ))
|
||||
))]
|
||||
cfg_if! { @__identity $( $tokens )* }
|
||||
|
||||
// Recurse to emit all other items in `$rest`, and when we do so add all
|
||||
// our `$yes` matchers to the list of `$no` matchers as future emissions
|
||||
// will have to negate everything we just matched as well.
|
||||
cfg_if! {
|
||||
@__items ( $( $no , )* $( $yes , )? ) ;
|
||||
$( $rest , )*
|
||||
}
|
||||
};
|
||||
|
||||
// Internal macro to make __apply work out right for different match types,
|
||||
// because of how macros match/expand stuff.
|
||||
(@__identity $( $tokens:tt )* ) => {
|
||||
$( $tokens )*
|
||||
};
|
||||
}
|
||||
|
@ -261,6 +261,7 @@
|
||||
#![feature(const_socketaddr)]
|
||||
#![feature(const_trait_impl)]
|
||||
#![feature(container_error_extra)]
|
||||
#![feature(core_ffi_c)]
|
||||
#![feature(core_intrinsics)]
|
||||
#![feature(core_panic)]
|
||||
#![feature(custom_test_frameworks)]
|
||||
@ -315,6 +316,7 @@
|
||||
#![feature(prelude_import)]
|
||||
#![feature(ptr_as_uninit)]
|
||||
#![feature(ptr_internals)]
|
||||
#![feature(raw_os_nonzero)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(saturating_int_impl)]
|
||||
|
@ -1,156 +1,31 @@
|
||||
//! Platform-specific types, as defined by C.
|
||||
//!
|
||||
//! Code that interacts via FFI will almost certainly be using the
|
||||
//! base types provided by C, which aren't nearly as nicely defined
|
||||
//! as Rust's primitive types. This module provides types which will
|
||||
//! match those defined by C, so that code that interacts with C will
|
||||
//! refer to the correct types.
|
||||
//! Compatibility module for C platform-specific types. Use [`core::ffi`] instead.
|
||||
|
||||
#![stable(feature = "raw_os", since = "1.1.0")]
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
use core::num::*;
|
||||
|
||||
macro_rules! type_alias_no_nz {
|
||||
{
|
||||
$Docfile:tt, $Alias:ident = $Real:ty;
|
||||
$( $Cfg:tt )*
|
||||
} => {
|
||||
#[doc = include_str!($Docfile)]
|
||||
$( $Cfg )*
|
||||
macro_rules! alias_core_ffi {
|
||||
($($t:ident)*) => {$(
|
||||
#[stable(feature = "raw_os", since = "1.1.0")]
|
||||
pub type $Alias = $Real;
|
||||
}
|
||||
#[doc = include_str!(concat!("../../../../core/src/ffi/", stringify!($t), ".md"))]
|
||||
// Make this type alias appear cfg-dependent so that Clippy does not suggest
|
||||
// replacing expressions like `0 as c_char` with `0_i8`/`0_u8`. This #[cfg(all())] can be
|
||||
// removed after the false positive in https://github.com/rust-lang/rust-clippy/issues/8093
|
||||
// is fixed.
|
||||
#[cfg(all())]
|
||||
#[doc(cfg(all()))]
|
||||
pub type $t = core::ffi::$t;
|
||||
)*}
|
||||
}
|
||||
|
||||
// To verify that the NonZero types in this file's macro invocations correspond
|
||||
//
|
||||
// perl -n < library/std/src/os/raw/mod.rs -e 'next unless m/type_alias\!/; die "$_ ?" unless m/, (c_\w+) = (\w+), NonZero_(\w+) = NonZero(\w+)/; die "$_ ?" unless $3 eq $1 and $4 eq ucfirst $2'
|
||||
//
|
||||
// NB this does not check that the main c_* types are right.
|
||||
|
||||
macro_rules! type_alias {
|
||||
{
|
||||
$Docfile:tt, $Alias:ident = $Real:ty, $NZAlias:ident = $NZReal:ty;
|
||||
$( $Cfg:tt )*
|
||||
} => {
|
||||
type_alias_no_nz! { $Docfile, $Alias = $Real; $( $Cfg )* }
|
||||
|
||||
#[doc = concat!("Type alias for `NonZero` version of [`", stringify!($Alias), "`]")]
|
||||
#[unstable(feature = "raw_os_nonzero", issue = "82363")]
|
||||
$( $Cfg )*
|
||||
pub type $NZAlias = $NZReal;
|
||||
}
|
||||
}
|
||||
|
||||
type_alias! { "char.md", c_char = c_char_definition::c_char, NonZero_c_char = c_char_definition::NonZero_c_char;
|
||||
// Make this type alias appear cfg-dependent so that Clippy does not suggest
|
||||
// replacing `0 as c_char` with `0_i8`/`0_u8`. This #[cfg(all())] can be removed
|
||||
// after the false positive in https://github.com/rust-lang/rust-clippy/issues/8093
|
||||
// is fixed.
|
||||
#[cfg(all())]
|
||||
#[doc(cfg(all()))] }
|
||||
type_alias! { "schar.md", c_schar = i8, NonZero_c_schar = NonZeroI8; }
|
||||
type_alias! { "uchar.md", c_uchar = u8, NonZero_c_uchar = NonZeroU8; }
|
||||
type_alias! { "short.md", c_short = i16, NonZero_c_short = NonZeroI16; }
|
||||
type_alias! { "ushort.md", c_ushort = u16, NonZero_c_ushort = NonZeroU16; }
|
||||
type_alias! { "int.md", c_int = i32, NonZero_c_int = NonZeroI32; }
|
||||
type_alias! { "uint.md", c_uint = u32, NonZero_c_uint = NonZeroU32; }
|
||||
type_alias! { "long.md", c_long = i32, NonZero_c_long = NonZeroI32;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(any(target_pointer_width = "32", windows))] }
|
||||
type_alias! { "ulong.md", c_ulong = u32, NonZero_c_ulong = NonZeroU32;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(any(target_pointer_width = "32", windows))] }
|
||||
type_alias! { "long.md", c_long = i64, NonZero_c_long = NonZeroI64;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(all(target_pointer_width = "64", not(windows)))] }
|
||||
type_alias! { "ulong.md", c_ulong = u64, NonZero_c_ulong = NonZeroU64;
|
||||
#[doc(cfg(all()))]
|
||||
#[cfg(all(target_pointer_width = "64", not(windows)))] }
|
||||
type_alias! { "longlong.md", c_longlong = i64, NonZero_c_longlong = NonZeroI64; }
|
||||
type_alias! { "ulonglong.md", c_ulonglong = u64, NonZero_c_ulonglong = NonZeroU64; }
|
||||
type_alias_no_nz! { "float.md", c_float = f32; }
|
||||
type_alias_no_nz! { "double.md", c_double = f64; }
|
||||
|
||||
#[stable(feature = "raw_os", since = "1.1.0")]
|
||||
#[doc(no_inline)]
|
||||
pub use core::ffi::c_void;
|
||||
|
||||
/// Equivalent to C's `size_t` type, from `stddef.h` (or `cstddef` for C++).
|
||||
///
|
||||
/// This type is currently always [`usize`], however in the future there may be
|
||||
/// platforms where this is not the case.
|
||||
#[unstable(feature = "c_size_t", issue = "88345")]
|
||||
pub type c_size_t = usize;
|
||||
|
||||
/// Equivalent to C's `ptrdiff_t` type, from `stddef.h` (or `cstddef` for C++).
|
||||
///
|
||||
/// This type is currently always [`isize`], however in the future there may be
|
||||
/// platforms where this is not the case.
|
||||
#[unstable(feature = "c_size_t", issue = "88345")]
|
||||
pub type c_ptrdiff_t = isize;
|
||||
|
||||
/// Equivalent to C's `ssize_t` (on POSIX) or `SSIZE_T` (on Windows) type.
|
||||
///
|
||||
/// This type is currently always [`isize`], however in the future there may be
|
||||
/// platforms where this is not the case.
|
||||
#[unstable(feature = "c_size_t", issue = "88345")]
|
||||
pub type c_ssize_t = isize;
|
||||
|
||||
mod c_char_definition {
|
||||
cfg_if::cfg_if! {
|
||||
// These are the targets on which c_char is unsigned.
|
||||
if #[cfg(any(
|
||||
all(
|
||||
target_os = "linux",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "hexagon",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "s390x",
|
||||
target_arch = "riscv64",
|
||||
target_arch = "riscv32"
|
||||
)
|
||||
),
|
||||
all(target_os = "android", any(target_arch = "aarch64", target_arch = "arm")),
|
||||
all(target_os = "l4re", target_arch = "x86_64"),
|
||||
all(
|
||||
target_os = "freebsd",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "powerpc",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "riscv64"
|
||||
)
|
||||
),
|
||||
all(
|
||||
target_os = "netbsd",
|
||||
any(target_arch = "aarch64", target_arch = "arm", target_arch = "powerpc")
|
||||
),
|
||||
all(target_os = "openbsd", target_arch = "aarch64"),
|
||||
all(
|
||||
target_os = "vxworks",
|
||||
any(
|
||||
target_arch = "aarch64",
|
||||
target_arch = "arm",
|
||||
target_arch = "powerpc64",
|
||||
target_arch = "powerpc"
|
||||
)
|
||||
),
|
||||
all(target_os = "fuchsia", target_arch = "aarch64")
|
||||
))] {
|
||||
pub type c_char = u8;
|
||||
pub type NonZero_c_char = core::num::NonZeroU8;
|
||||
} else {
|
||||
// On every other target, c_char is signed.
|
||||
pub type c_char = i8;
|
||||
pub type NonZero_c_char = core::num::NonZeroI8;
|
||||
}
|
||||
}
|
||||
alias_core_ffi! {
|
||||
c_char c_schar c_uchar
|
||||
c_short c_ushort
|
||||
c_int c_uint
|
||||
c_long c_ulong
|
||||
c_longlong c_ulonglong
|
||||
c_float
|
||||
c_double
|
||||
c_void
|
||||
}
|
||||
|
@ -3,11 +3,11 @@
|
||||
use crate::io::{self, Error, ErrorKind};
|
||||
use crate::mem;
|
||||
use crate::num::NonZeroI32;
|
||||
use crate::os::raw::NonZero_c_int;
|
||||
use crate::ptr;
|
||||
use crate::sys;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::process::process_common::*;
|
||||
use core::ffi::NonZero_c_int;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use crate::os::linux::process::PidFd;
|
||||
|
@ -3,12 +3,12 @@
|
||||
use crate::io;
|
||||
use crate::io::ErrorKind;
|
||||
use crate::num::NonZeroI32;
|
||||
use crate::os::raw::NonZero_c_int;
|
||||
use crate::sys;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::pipe::AnonPipe;
|
||||
use crate::sys::process::process_common::*;
|
||||
use crate::sys::unix::unsupported::*;
|
||||
use core::ffi::NonZero_c_int;
|
||||
|
||||
use libc::{c_int, pid_t};
|
||||
|
||||
|
@ -2,11 +2,11 @@
|
||||
use crate::fmt;
|
||||
use crate::io::{self, Error, ErrorKind};
|
||||
use crate::num::NonZeroI32;
|
||||
use crate::os::raw::NonZero_c_int;
|
||||
use crate::sys;
|
||||
use crate::sys::cvt;
|
||||
use crate::sys::process::process_common::*;
|
||||
use crate::sys_common::thread;
|
||||
use core::ffi::NonZero_c_int;
|
||||
use libc::RTP_ID;
|
||||
use libc::{self, c_char, c_int};
|
||||
|
||||
|
@ -5,9 +5,9 @@
|
||||
#![unstable(issue = "none", feature = "windows_c")]
|
||||
|
||||
use crate::mem;
|
||||
use crate::os::raw::NonZero_c_ulong;
|
||||
use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort};
|
||||
use crate::ptr;
|
||||
use core::ffi::NonZero_c_ulong;
|
||||
|
||||
use libc::{c_void, size_t, wchar_t};
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 67b768c0b660a069a45f0e5d8ae2f679df1022ab
|
||||
Subproject commit 3f255ed40b8c82a0434088568fbed270dc31bf00
|
@ -1 +1 @@
|
||||
Subproject commit beea0a3cdc3885375342fd010f9ad658e6a5e09a
|
||||
Subproject commit c55611dd6c58bdeb52423b5c52fd0f3c93615ba8
|
@ -1 +1 @@
|
||||
Subproject commit 90993eeac93dbf9388992de92965f99cf6f29a03
|
||||
Subproject commit f6d6126fc96ecf4a7f7d22da330df9506293b0d0
|
@ -1 +1 @@
|
||||
Subproject commit 70fc73a6b908e08e66aa0306856c5211312f6c05
|
||||
Subproject commit 9d289c05fce7254b99c6a0d354d84abb7fd7a032
|
@ -1 +1 @@
|
||||
Subproject commit 18c0055b8aea49391e8f758a4400097999c9cf1e
|
||||
Subproject commit 2a928483a20bb306a7399c0468234db90d89afb5
|
@ -1 +1 @@
|
||||
Subproject commit 62f58394ba7b203f55ac35ddcc4c0b79578f5706
|
||||
Subproject commit 32f2a5b4e7545318846185198542230170dd8a42
|
@ -178,7 +178,7 @@ impl ConditionalPass {
|
||||
|
||||
'outer: for (line_no, md_line) in md_lines.enumerate() {
|
||||
loop {
|
||||
let source_line = src_lines.next().expect("could not find markdown in source");
|
||||
let source_line = src_lines.next()?;
|
||||
match source_line.find(md_line) {
|
||||
Some(offset) => {
|
||||
if line_no == starting_line {
|
||||
|
@ -24,6 +24,7 @@ pub fn eliminates_runtime_check_when_align_1(
|
||||
x: &Struct<WrapperWithAlign1<dyn Trait>>
|
||||
) -> &WrapperWithAlign1<dyn Trait> {
|
||||
// CHECK: load [[USIZE:i[0-9]+]], {{.+}} !range [[RANGE_META:![0-9]+]]
|
||||
// CHECK-NOT: llvm.umax
|
||||
// CHECK-NOT: icmp
|
||||
// CHECK-NOT: select
|
||||
// CHECK: ret
|
||||
@ -36,8 +37,7 @@ pub fn does_not_eliminate_runtime_check_when_align_2(
|
||||
x: &Struct<WrapperWithAlign2<dyn Trait>>
|
||||
) -> &WrapperWithAlign2<dyn Trait> {
|
||||
// CHECK: [[X0:%[0-9]+]] = load [[USIZE]], {{.+}} !range [[RANGE_META]]
|
||||
// CHECK: [[X1:%[0-9]+]] = icmp {{.+}} [[X0]]
|
||||
// CHECK: [[X2:%[0-9]+]] = select {{.+}} [[X1]]
|
||||
// CHECK: {{icmp|llvm.umax}}
|
||||
// CHECK: ret
|
||||
&x.dst
|
||||
}
|
||||
|
1
src/test/rustdoc-ui/auxiliary/module_macro_doc.rs
Normal file
1
src/test/rustdoc-ui/auxiliary/module_macro_doc.rs
Normal file
@ -0,0 +1 @@
|
||||
//! [`long_cat`] is really long
|
12
src/test/rustdoc-ui/macro-docs.rs
Normal file
12
src/test/rustdoc-ui/macro-docs.rs
Normal file
@ -0,0 +1,12 @@
|
||||
// check-pass
|
||||
|
||||
macro_rules! m {
|
||||
() => {
|
||||
/// A
|
||||
//~^ WARNING
|
||||
#[path = "auxiliary/module_macro_doc.rs"]
|
||||
pub mod mymodule;
|
||||
}
|
||||
}
|
||||
|
||||
m!();
|
20
src/test/rustdoc-ui/macro-docs.stderr
Normal file
20
src/test/rustdoc-ui/macro-docs.stderr
Normal file
@ -0,0 +1,20 @@
|
||||
warning: unresolved link to `long_cat`
|
||||
--> $DIR/macro-docs.rs:5:9
|
||||
|
|
||||
LL | /// A
|
||||
| ^^^^^
|
||||
...
|
||||
LL | m!();
|
||||
| ---- in this macro invocation
|
||||
|
|
||||
= note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
|
||||
= note: the link appears in this line:
|
||||
|
||||
[`long_cat`] is really long
|
||||
^^^^^^^^^^
|
||||
= note: no item named `long_cat` in scope
|
||||
= help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
|
||||
= note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
warning: 1 warning emitted
|
||||
|
0
src/test/rustdoc-ui/macro-docs.stdout
Normal file
0
src/test/rustdoc-ui/macro-docs.stdout
Normal file
@ -8,6 +8,12 @@ LL | fn attemptTraverse(&self, room: &Room, directionStr: &str) -> Result<&R
|
||||
...
|
||||
LL | Some(entry) => Ok(entry),
|
||||
| ^^^^^^^^^ ...but data from `room` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter
|
||||
|
|
||||
LL | fn attemptTraverse<'a>(&'a self, room: &'a Room, directionStr: &str) -> Result<&Room, &str> {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0308]: `match` arms have incompatible types
|
||||
--> $DIR/issue-17728.rs:109:14
|
||||
|
@ -7,6 +7,12 @@ LL | fn foo<'a>(&self, x: &i32) -> &i32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | x
|
||||
| ^ ...but data from `x` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn foo<'a>(&'a self, x: &'a i32) -> &i32 {
|
||||
| ++ ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -7,6 +7,12 @@ LL | fn foo<'a>(&self, x: &Foo) -> &Foo {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | if true { x } else { self }
|
||||
| ^ ...but data from `x` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn foo<'a>(&'a self, x: &'a Foo) -> &Foo {
|
||||
| ++ ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,6 +5,12 @@ LL | fn foo(x: &mut Vec<&u8>, y: &u8) {
|
||||
| --- --- these two types are declared with different lifetimes...
|
||||
LL | x.push(y);
|
||||
| ^ ...but data from `y` flows into `x` here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn foo<'a>(x: &mut Vec<&'a u8>, y: &'a u8) {
|
||||
| ++++ ++ ++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -5,6 +5,12 @@ LL | fn a(self: Pin<&Foo>, f: &Foo) -> &Foo { f }
|
||||
| ---- ---- ^ ...but data from `f` is returned here
|
||||
| |
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn a<'a>(self: Pin<&'a Foo>, f: &'a Foo) -> &Foo { f }
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:8:76
|
||||
@ -13,6 +19,12 @@ LL | fn c(self: Pin<&Self>, f: &Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self,
|
||||
| ---- ----------------- ^ ...but data from `f` is returned here
|
||||
| |
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn c<'a>(self: Pin<&'a Self>, f: &'a Foo, g: &Foo) -> (Pin<&Foo>, &Foo) { (self, f) }
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/arbitrary_self_types_pin_lifetime_mismatch.rs:13:58
|
||||
|
@ -7,6 +7,12 @@ LL | fn ref_self(&self, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/lt-ref-self.rs:17:9
|
||||
@ -17,6 +23,12 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/lt-ref-self.rs:21:9
|
||||
@ -27,6 +39,12 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/lt-ref-self.rs:25:9
|
||||
@ -37,6 +55,12 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/lt-ref-self.rs:29:9
|
||||
@ -47,6 +71,12 @@ LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/lt-ref-self.rs:33:9
|
||||
@ -57,6 +87,12 @@ LL | fn box_pin_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_pin_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -7,6 +7,12 @@ LL | fn ref_self(&mut self, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_self<'a>(&'a mut self, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-self.rs:17:9
|
||||
@ -17,6 +23,12 @@ LL | fn ref_Self(self: &mut Self, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_Self<'a>(self: &'a mut Self, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-self.rs:21:9
|
||||
@ -27,6 +39,12 @@ LL | fn box_ref_Self(self: Box<&mut Self>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_ref_Self<'a>(self: Box<&'a mut Self>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-self.rs:25:9
|
||||
@ -37,6 +55,12 @@ LL | fn pin_ref_Self(self: Pin<&mut Self>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn pin_ref_Self<'a>(self: Pin<&'a mut Self>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-self.rs:29:9
|
||||
@ -47,6 +71,12 @@ LL | fn box_box_ref_Self(self: Box<Box<&mut Self>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a mut Self>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-self.rs:33:9
|
||||
@ -57,6 +87,12 @@ LL | fn box_pin_ref_Self(self: Box<Pin<&mut Self>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&'a mut Self>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
|
||||
|
@ -7,6 +7,12 @@ LL | fn ref_Struct(self: &mut Struct, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_Struct<'a>(self: &'a mut Struct, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-struct.rs:15:9
|
||||
@ -17,6 +23,12 @@ LL | fn box_ref_Struct(self: Box<&mut Struct>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_ref_Struct<'a>(self: Box<&'a mut Struct>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-struct.rs:19:9
|
||||
@ -27,6 +39,12 @@ LL | fn pin_ref_Struct(self: Pin<&mut Struct>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn pin_ref_Struct<'a>(self: Pin<&'a mut Struct>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-struct.rs:23:9
|
||||
@ -37,6 +55,12 @@ LL | fn box_box_ref_Struct(self: Box<Box<&mut Struct>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_box_ref_Struct<'a>(self: Box<Box<&'a mut Struct>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-mut-struct.rs:27:9
|
||||
@ -47,6 +71,12 @@ LL | fn box_pin_ref_Struct(self: Box<Pin<&mut Struct>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_pin_ref_Struct<'a>(self: Box<Pin<&'a mut Struct>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -7,6 +7,12 @@ LL | fn ref_self(&self, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_self<'a>(&'a self, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-self.rs:27:9
|
||||
@ -17,6 +23,12 @@ LL | fn ref_Self(self: &Self, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_Self<'a>(self: &'a Self, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-self.rs:31:9
|
||||
@ -27,6 +39,12 @@ LL | fn box_ref_Self(self: Box<&Self>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_ref_Self<'a>(self: Box<&'a Self>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-self.rs:35:9
|
||||
@ -37,6 +55,12 @@ LL | fn pin_ref_Self(self: Pin<&Self>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn pin_ref_Self<'a>(self: Pin<&'a Self>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-self.rs:39:9
|
||||
@ -47,6 +71,12 @@ LL | fn box_box_ref_Self(self: Box<Box<&Self>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_box_ref_Self<'a>(self: Box<Box<&'a Self>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-self.rs:43:9
|
||||
@ -57,6 +87,12 @@ LL | fn box_pin_ref_Self(self: Box<Pin<&Self>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_pin_ref_Self<'a>(self: Box<Pin<&'a Self>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-self.rs:47:9
|
||||
@ -67,6 +103,12 @@ LL | fn wrap_ref_Self_Self(self: Wrap<&Self, Self>, f: &u8) -> &u8 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn wrap_ref_Self_Self<'a>(self: Wrap<&'a Self, Self>, f: &'a u8) -> &u8 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error: aborting due to 7 previous errors
|
||||
|
||||
|
@ -7,6 +7,12 @@ LL | fn ref_Struct(self: &Struct, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn ref_Struct<'a>(self: &'a Struct, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-struct.rs:15:9
|
||||
@ -17,6 +23,12 @@ LL | fn box_ref_Struct(self: Box<&Struct>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_ref_Struct<'a>(self: Box<&'a Struct>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-struct.rs:19:9
|
||||
@ -27,6 +39,12 @@ LL | fn pin_ref_Struct(self: Pin<&Struct>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn pin_ref_Struct<'a>(self: Pin<&'a Struct>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-struct.rs:23:9
|
||||
@ -37,6 +55,12 @@ LL | fn box_box_ref_Struct(self: Box<Box<&Struct>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_box_ref_Struct<'a>(self: Box<Box<&'a Struct>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error[E0623]: lifetime mismatch
|
||||
--> $DIR/ref-struct.rs:27:9
|
||||
@ -47,6 +71,12 @@ LL | fn box_pin_Struct(self: Box<Pin<&Struct>>, f: &u32) -> &u32 {
|
||||
| this parameter and the return type are declared with different lifetimes...
|
||||
LL | f
|
||||
| ^ ...but data from `f` is returned here
|
||||
|
|
||||
= note: each elided lifetime in input position becomes a distinct lifetime
|
||||
help: consider introducing a named lifetime parameter and update trait if needed
|
||||
|
|
||||
LL | fn box_pin_Struct<'a>(self: Box<Pin<&'a Struct>>, f: &'a u32) -> &u32 {
|
||||
| ++++ ++ ++
|
||||
|
||||
error: aborting due to 5 previous errors
|
||||
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e05a543f74dbdd0580b2bd35ddb7f8e144d9edda
|
||||
Subproject commit c6b3f687d5d9917b626f80a730552a185052ff28
|
@ -46,7 +46,7 @@
|
||||
// pointer regardless of the target architecture. As a result,
|
||||
// we must use `#[cfg(windows)]` to conditionally compile the
|
||||
// correct `VaList` structure for windows.
|
||||
"library/core/src/ffi.rs",
|
||||
"library/core/src/ffi/mod.rs",
|
||||
"library/std/src/sys/", // Platform-specific code for std lives here.
|
||||
"library/std/src/os", // Platform-specific public interfaces
|
||||
// Temporary `std` exceptions
|
||||
|
Loading…
Reference in New Issue
Block a user