mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
Re-format code with new rustfmt
This commit is contained in:
parent
db3e2bacb6
commit
917f6540ed
@ -1213,8 +1213,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
|
|||||||
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
|
DisallowTildeConstContext::Fn(FnKind::Fn(_, ident, ..)) => {
|
||||||
errors::TildeConstReason::Function { ident: ident.span }
|
errors::TildeConstReason::Function { ident: ident.span }
|
||||||
}
|
}
|
||||||
&DisallowTildeConstContext::Trait(span) => errors::TildeConstReason::Trait { span },
|
&DisallowTildeConstContext::Trait(span) => {
|
||||||
&DisallowTildeConstContext::Impl(span) => errors::TildeConstReason::Impl { span },
|
errors::TildeConstReason::Trait { span }
|
||||||
|
}
|
||||||
|
&DisallowTildeConstContext::Impl(span) => {
|
||||||
|
errors::TildeConstReason::Impl { span }
|
||||||
|
}
|
||||||
DisallowTildeConstContext::TraitObject => {
|
DisallowTildeConstContext::TraitObject => {
|
||||||
errors::TildeConstReason::TraitObject
|
errors::TildeConstReason::TraitObject
|
||||||
}
|
}
|
||||||
@ -1446,9 +1450,7 @@ fn deny_equality_constraints(
|
|||||||
id: rustc_ast::node_id::DUMMY_NODE_ID,
|
id: rustc_ast::node_id::DUMMY_NODE_ID,
|
||||||
ident: *ident,
|
ident: *ident,
|
||||||
gen_args,
|
gen_args,
|
||||||
kind: AssocConstraintKind::Equality {
|
kind: AssocConstraintKind::Equality { term: predicate.rhs_ty.clone().into() },
|
||||||
term: predicate.rhs_ty.clone().into(),
|
|
||||||
},
|
|
||||||
span: ident.span,
|
span: ident.span,
|
||||||
});
|
});
|
||||||
// Add `<Bar = RhsTy>` to `Foo`.
|
// Add `<Bar = RhsTy>` to `Foo`.
|
||||||
@ -1461,11 +1463,7 @@ fn deny_equality_constraints(
|
|||||||
},
|
},
|
||||||
empty_args => {
|
empty_args => {
|
||||||
*empty_args = Some(
|
*empty_args = Some(
|
||||||
AngleBracketedArgs {
|
AngleBracketedArgs { span: ident.span, args: thin_vec![arg] }.into(),
|
||||||
span: ident.span,
|
|
||||||
args: thin_vec![arg],
|
|
||||||
}
|
|
||||||
.into(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,8 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
|||||||
|
|
||||||
if let Some(adt) = local_ty.ty_adt_def()
|
if let Some(adt) = local_ty.ty_adt_def()
|
||||||
&& adt.repr().packed()
|
&& adt.repr().packed()
|
||||||
&& let ExpnKind::Macro(MacroKind::Derive, name) = self.body.span.ctxt().outer_expn_data().kind
|
&& let ExpnKind::Macro(MacroKind::Derive, name) =
|
||||||
|
self.body.span.ctxt().outer_expn_data().kind
|
||||||
{
|
{
|
||||||
err.note(format!("`#[derive({name})]` triggers a move because taking references to the fields of a packed struct is undefined behaviour"));
|
err.note(format!("`#[derive({name})]` triggers a move because taking references to the fields of a packed struct is undefined behaviour"));
|
||||||
}
|
}
|
||||||
|
@ -617,10 +617,17 @@ fn report_missing_placeholders(
|
|||||||
let placeholders = pieces
|
let placeholders = pieces
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|piece| {
|
.filter_map(|piece| {
|
||||||
if let parse::Piece::NextArgument(argument) = piece && let ArgumentNamed(binding) = argument.position {
|
if let parse::Piece::NextArgument(argument) = piece
|
||||||
let span = fmt_span.from_inner(InnerSpan::new(argument.position_span.start, argument.position_span.end));
|
&& let ArgumentNamed(binding) = argument.position
|
||||||
|
{
|
||||||
|
let span = fmt_span.from_inner(InnerSpan::new(
|
||||||
|
argument.position_span.start,
|
||||||
|
argument.position_span.end,
|
||||||
|
));
|
||||||
Some((span, binding))
|
Some((span, binding))
|
||||||
} else { None }
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
@ -114,9 +114,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
use rustc_middle::mir::BinOp::*;
|
use rustc_middle::mir::BinOp::*;
|
||||||
|
|
||||||
// Performs appropriate non-deterministic adjustments of NaN results.
|
// Performs appropriate non-deterministic adjustments of NaN results.
|
||||||
let adjust_nan = |f: F| -> F {
|
let adjust_nan =
|
||||||
if f.is_nan() { M::generate_nan(self, &[l, r]) } else { f }
|
|f: F| -> F { if f.is_nan() { M::generate_nan(self, &[l, r]) } else { f } };
|
||||||
};
|
|
||||||
|
|
||||||
let val = match bin_op {
|
let val = match bin_op {
|
||||||
Eq => ImmTy::from_bool(l == r, *self.tcx),
|
Eq => ImmTy::from_bool(l == r, *self.tcx),
|
||||||
|
@ -74,7 +74,9 @@ pub fn features(sess: &Session, krate_attrs: &[Attribute], crate_name: Symbol) -
|
|||||||
// - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher
|
// - E.g. enable `test_2018_feature` if `features_edition` is 2018 or higher
|
||||||
let mut edition_enabled_features = FxHashSet::default();
|
let mut edition_enabled_features = FxHashSet::default();
|
||||||
for f in UNSTABLE_FEATURES {
|
for f in UNSTABLE_FEATURES {
|
||||||
if let Some(edition) = f.feature.edition && edition <= features_edition {
|
if let Some(edition) = f.feature.edition
|
||||||
|
&& edition <= features_edition
|
||||||
|
{
|
||||||
// FIXME(Manishearth) there is currently no way to set lib features by
|
// FIXME(Manishearth) there is currently no way to set lib features by
|
||||||
// edition.
|
// edition.
|
||||||
edition_enabled_features.insert(f.feature.name);
|
edition_enabled_features.insert(f.feature.name);
|
||||||
@ -251,8 +253,7 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
let trees: Vec<_> = stream
|
let trees: Vec<_> = stream
|
||||||
.0
|
.0
|
||||||
.iter()
|
.iter()
|
||||||
.flat_map(|tree| {
|
.flat_map(|tree| match tree.clone() {
|
||||||
match tree.clone() {
|
|
||||||
AttrTokenTree::Attributes(mut data) => {
|
AttrTokenTree::Attributes(mut data) => {
|
||||||
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
|
data.attrs.flat_map_in_place(|attr| self.process_cfg_attr(&attr));
|
||||||
|
|
||||||
@ -277,7 +278,6 @@ impl<'a> StripUnconfigured<'a> {
|
|||||||
AttrTokenTree::Token(token, spacing) => {
|
AttrTokenTree::Token(token, spacing) => {
|
||||||
Some(AttrTokenTree::Token(token, spacing)).into_iter()
|
Some(AttrTokenTree::Token(token, spacing)).into_iter()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
AttrTokenStream::new(trees)
|
AttrTokenStream::new(trees)
|
||||||
|
@ -194,8 +194,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
|
|
||||||
self.add_bounds(
|
self.add_bounds(
|
||||||
param_ty,
|
param_ty,
|
||||||
ast_bounds.iter().filter(|bound| {
|
ast_bounds.iter().filter(|bound| match filter {
|
||||||
match filter {
|
|
||||||
PredicateFilter::All
|
PredicateFilter::All
|
||||||
| PredicateFilter::SelfOnly
|
| PredicateFilter::SelfOnly
|
||||||
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
|
| PredicateFilter::SelfAndAssociatedTypeBounds => true,
|
||||||
@ -209,7 +208,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}),
|
}),
|
||||||
&mut bounds,
|
&mut bounds,
|
||||||
ty::List::empty(),
|
ty::List::empty(),
|
||||||
|
@ -206,15 +206,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
&& let parent = hir.get_parent_item(hir.local_def_id_to_hir_id(def_id))
|
&& let parent = hir.get_parent_item(hir.local_def_id_to_hir_id(def_id))
|
||||||
&& let Some(generics) = hir.get_generics(parent.def_id)
|
&& let Some(generics) = hir.get_generics(parent.def_id)
|
||||||
{
|
{
|
||||||
if generics.bounds_for_param(def_id)
|
if generics.bounds_for_param(def_id).flat_map(|pred| pred.bounds.iter()).any(
|
||||||
.flat_map(|pred| pred.bounds.iter())
|
|b| match b {
|
||||||
.any(|b| match b {
|
|
||||||
hir::GenericBound::Trait(t, ..) => {
|
hir::GenericBound::Trait(t, ..) => {
|
||||||
t.trait_ref.trait_def_id().as_ref() == Some(best_trait)
|
t.trait_ref.trait_def_id().as_ref() == Some(best_trait)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
},
|
||||||
{
|
) {
|
||||||
// The type param already has a bound for `trait_name`, we just need to
|
// The type param already has a bound for `trait_name`, we just need to
|
||||||
// change the associated type.
|
// change the associated type.
|
||||||
err.span_suggestion_verbose(
|
err.span_suggestion_verbose(
|
||||||
@ -227,15 +226,14 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
|||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
} else if suggest_constraining_type_param(
|
} else if suggest_constraining_type_param(
|
||||||
self.tcx(),
|
self.tcx(),
|
||||||
generics,
|
generics,
|
||||||
&mut err,
|
&mut err,
|
||||||
&ty_param_name,
|
&ty_param_name,
|
||||||
&trait_name,
|
&trait_name,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
)
|
) && suggested_name != assoc_name.name
|
||||||
&& suggested_name != assoc_name.name
|
|
||||||
{
|
{
|
||||||
// We suggested constraining a type parameter, but the associated type on it
|
// We suggested constraining a type parameter, but the associated type on it
|
||||||
// was also not an exact match, so we also suggest changing it.
|
// was also not an exact match, so we also suggest changing it.
|
||||||
|
@ -3185,19 +3185,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
sym::offset_of_enum,
|
sym::offset_of_enum,
|
||||||
ident.span,
|
ident.span,
|
||||||
"using enums in offset_of is experimental",
|
"using enums in offset_of is experimental",
|
||||||
).emit();
|
)
|
||||||
|
.emit();
|
||||||
}
|
}
|
||||||
|
|
||||||
let Some((index, variant)) = container_def.variants()
|
let Some((index, variant)) = container_def
|
||||||
|
.variants()
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident) else {
|
.find(|(_, v)| v.ident(self.tcx).normalize_to_macros_2_0() == ident)
|
||||||
|
else {
|
||||||
let mut err = type_error_struct!(
|
let mut err = type_error_struct!(
|
||||||
self.tcx().sess,
|
self.tcx().sess,
|
||||||
ident.span,
|
ident.span,
|
||||||
container,
|
container,
|
||||||
E0599,
|
E0599,
|
||||||
"no variant named `{ident}` found for enum `{container}`",
|
"no variant named `{ident}` found for enum `{container}`",
|
||||||
);
|
);
|
||||||
err.span_label(field.span, "variant not found");
|
err.span_label(field.span, "variant not found");
|
||||||
err.emit();
|
err.emit();
|
||||||
break;
|
break;
|
||||||
@ -3209,7 +3212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
container,
|
container,
|
||||||
E0795,
|
E0795,
|
||||||
"`{ident}` is an enum variant; expected field at end of `offset_of`",
|
"`{ident}` is an enum variant; expected field at end of `offset_of`",
|
||||||
);
|
);
|
||||||
err.span_label(field.span, "enum variant");
|
err.span_label(field.span, "enum variant");
|
||||||
err.emit();
|
err.emit();
|
||||||
break;
|
break;
|
||||||
@ -3217,16 +3220,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let (subident, sub_def_scope) =
|
let (subident, sub_def_scope) =
|
||||||
self.tcx.adjust_ident_and_get_scope(subfield, variant.def_id, block);
|
self.tcx.adjust_ident_and_get_scope(subfield, variant.def_id, block);
|
||||||
|
|
||||||
let Some((subindex, field)) = variant.fields
|
let Some((subindex, field)) = variant
|
||||||
|
.fields
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident) else {
|
.find(|(_, f)| f.ident(self.tcx).normalize_to_macros_2_0() == subident)
|
||||||
|
else {
|
||||||
let mut err = type_error_struct!(
|
let mut err = type_error_struct!(
|
||||||
self.tcx().sess,
|
self.tcx().sess,
|
||||||
ident.span,
|
ident.span,
|
||||||
container,
|
container,
|
||||||
E0609,
|
E0609,
|
||||||
"no field named `{subfield}` on enum variant `{container}::{ident}`",
|
"no field named `{subfield}` on enum variant `{container}::{ident}`",
|
||||||
);
|
);
|
||||||
err.span_label(field.span, "this enum variant...");
|
err.span_label(field.span, "this enum variant...");
|
||||||
err.span_label(subident.span, "...does not have this field");
|
err.span_label(subident.span, "...does not have this field");
|
||||||
err.emit();
|
err.emit();
|
||||||
|
@ -1864,35 +1864,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
&& let ExprBindingObligation(_, _, hir_id, ..) = code
|
&& let ExprBindingObligation(_, _, hir_id, ..) = code
|
||||||
&& !fn_sig.output().is_unit()
|
&& !fn_sig.output().is_unit()
|
||||||
{
|
{
|
||||||
let mut block_num = 0;
|
let mut block_num = 0;
|
||||||
let mut found_semi = false;
|
let mut found_semi = false;
|
||||||
for (_, node) in self.tcx.hir().parent_iter(hir_id) {
|
for (_, node) in self.tcx.hir().parent_iter(hir_id) {
|
||||||
match node {
|
match node {
|
||||||
hir::Node::Stmt(stmt) => if let hir::StmtKind::Semi(ref expr) = stmt.kind {
|
hir::Node::Stmt(stmt) => {
|
||||||
|
if let hir::StmtKind::Semi(ref expr) = stmt.kind {
|
||||||
let expr_ty = self.typeck_results.borrow().expr_ty(expr);
|
let expr_ty = self.typeck_results.borrow().expr_ty(expr);
|
||||||
let return_ty = fn_sig.output();
|
let return_ty = fn_sig.output();
|
||||||
if !matches!(expr.kind, hir::ExprKind::Ret(..)) &&
|
if !matches!(expr.kind, hir::ExprKind::Ret(..))
|
||||||
self.can_coerce(expr_ty, return_ty) {
|
&& self.can_coerce(expr_ty, return_ty)
|
||||||
|
{
|
||||||
found_semi = true;
|
found_semi = true;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
hir::Node::Block(_block) => if found_semi {
|
}
|
||||||
|
hir::Node::Block(_block) => {
|
||||||
|
if found_semi {
|
||||||
block_num += 1;
|
block_num += 1;
|
||||||
}
|
}
|
||||||
hir::Node::Item(item) => if let hir::ItemKind::Fn(..) = item.kind {
|
}
|
||||||
|
hir::Node::Item(item) => {
|
||||||
|
if let hir::ItemKind::Fn(..) = item.kind {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
if block_num > 1 && found_semi {
|
}
|
||||||
diag.span_suggestion_verbose(
|
if block_num > 1 && found_semi {
|
||||||
span.shrink_to_lo(),
|
diag.span_suggestion_verbose(
|
||||||
"you might have meant to return this to infer its type parameters",
|
span.shrink_to_lo(),
|
||||||
"return ",
|
"you might have meant to return this to infer its type parameters",
|
||||||
Applicability::MaybeIncorrect,
|
"return ",
|
||||||
);
|
Applicability::MaybeIncorrect,
|
||||||
}
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
diag.emit();
|
diag.emit();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
//! Give useful errors and suggestions to users when an item can't be
|
//! Give useful errors and suggestions to users when an item can't be
|
||||||
//! found or is otherwise invalid.
|
//! found or is otherwise invalid.
|
||||||
|
|
||||||
|
// ignore-tidy-filelength
|
||||||
|
|
||||||
use crate::errors;
|
use crate::errors;
|
||||||
use crate::errors::{CandidateTraitNote, NoAssociatedItem};
|
use crate::errors::{CandidateTraitNote, NoAssociatedItem};
|
||||||
use crate::Expectation;
|
use crate::Expectation;
|
||||||
@ -369,25 +371,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
tcx.is_diagnostic_item(sym::write_macro, def_id)
|
tcx.is_diagnostic_item(sym::write_macro, def_id)
|
||||||
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
|
|| tcx.is_diagnostic_item(sym::writeln_macro, def_id)
|
||||||
}) && item_name.name == Symbol::intern("write_fmt");
|
}) && item_name.name == Symbol::intern("write_fmt");
|
||||||
let mut err =
|
let mut err = if is_write && let SelfSource::MethodCall(rcvr_expr) = source {
|
||||||
if is_write && let SelfSource::MethodCall(rcvr_expr) = source
|
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
|
||||||
{
|
} else {
|
||||||
self.suggest_missing_writer(rcvr_ty, rcvr_expr)
|
tcx.sess.create_err(NoAssociatedItem {
|
||||||
} else {
|
span,
|
||||||
tcx.sess.create_err(NoAssociatedItem {
|
item_kind,
|
||||||
span,
|
item_name,
|
||||||
item_kind,
|
ty_prefix: if trait_missing_method {
|
||||||
item_name,
|
// FIXME(mu001999) E0599 maybe not suitable here because it is for types
|
||||||
ty_prefix: if trait_missing_method {
|
Cow::from("trait")
|
||||||
// FIXME(mu001999) E0599 maybe not suitable here because it is for types
|
} else {
|
||||||
Cow::from("trait")
|
rcvr_ty.prefix_string(self.tcx)
|
||||||
} else {
|
},
|
||||||
rcvr_ty.prefix_string(self.tcx)
|
ty_str: ty_str_reported,
|
||||||
},
|
trait_missing_method,
|
||||||
ty_str: ty_str_reported,
|
})
|
||||||
trait_missing_method,
|
};
|
||||||
})
|
|
||||||
};
|
|
||||||
if tcx.sess.source_map().is_multiline(sugg_span) {
|
if tcx.sess.source_map().is_multiline(sugg_span) {
|
||||||
err.span_label(sugg_span.with_hi(span.lo()), "");
|
err.span_label(sugg_span.with_hi(span.lo()), "");
|
||||||
}
|
}
|
||||||
@ -1240,20 +1240,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// If an appropriate error source is not found, check method chain for possible candiates
|
// If an appropriate error source is not found, check method chain for possible candiates
|
||||||
if unsatisfied_predicates.is_empty() && let Mode::MethodCall = mode && let SelfSource::MethodCall(mut source_expr) = source {
|
if unsatisfied_predicates.is_empty()
|
||||||
|
&& let Mode::MethodCall = mode
|
||||||
|
&& let SelfSource::MethodCall(mut source_expr) = source
|
||||||
|
{
|
||||||
let mut stack_methods = vec![];
|
let mut stack_methods = vec![];
|
||||||
while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, method_span) =
|
while let hir::ExprKind::MethodCall(_path_segment, rcvr_expr, _args, method_span) =
|
||||||
source_expr.kind
|
source_expr.kind
|
||||||
{
|
{
|
||||||
// Pop the matching receiver, to align on it's notional span
|
// Pop the matching receiver, to align on it's notional span
|
||||||
if let Some(prev_match) = stack_methods.pop() {
|
if let Some(prev_match) = stack_methods.pop() {
|
||||||
err.span_label(method_span, format!("{item_kind} `{item_name}` is available on `{prev_match}`"));
|
err.span_label(
|
||||||
|
method_span,
|
||||||
|
format!("{item_kind} `{item_name}` is available on `{prev_match}`"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
let rcvr_ty = self.resolve_vars_if_possible(
|
let rcvr_ty = self.resolve_vars_if_possible(
|
||||||
self.typeck_results
|
self.typeck_results
|
||||||
.borrow()
|
.borrow()
|
||||||
.expr_ty_adjusted_opt(rcvr_expr)
|
.expr_ty_adjusted_opt(rcvr_expr)
|
||||||
.unwrap_or(Ty::new_misc_error(self.tcx)),);
|
.unwrap_or(Ty::new_misc_error(self.tcx)),
|
||||||
|
);
|
||||||
|
|
||||||
for _matched_method in self.probe_for_name_many(
|
for _matched_method in self.probe_for_name_many(
|
||||||
Mode::MethodCall,
|
Mode::MethodCall,
|
||||||
@ -1262,15 +1269,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
IsSuggestion(true),
|
IsSuggestion(true),
|
||||||
rcvr_ty,
|
rcvr_ty,
|
||||||
source_expr.hir_id,
|
source_expr.hir_id,
|
||||||
ProbeScope::TraitsInScope,) {
|
ProbeScope::TraitsInScope,
|
||||||
// found a match, push to stack
|
) {
|
||||||
stack_methods.push(rcvr_ty);
|
// found a match, push to stack
|
||||||
|
stack_methods.push(rcvr_ty);
|
||||||
}
|
}
|
||||||
source_expr = rcvr_expr;
|
source_expr = rcvr_expr;
|
||||||
}
|
}
|
||||||
// If there is a match at the start of the chain, add a label for it too!
|
// If there is a match at the start of the chain, add a label for it too!
|
||||||
if let Some(prev_match) = stack_methods.pop() {
|
if let Some(prev_match) = stack_methods.pop() {
|
||||||
err.span_label(source_expr.span, format!("{item_kind} `{item_name}` is available on `{prev_match}`"));
|
err.span_label(
|
||||||
|
source_expr.span,
|
||||||
|
format!("{item_kind} `{item_name}` is available on `{prev_match}`"),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
|
self.note_derefed_ty_has_method(&mut err, source, rcvr_ty, item_name, expected);
|
||||||
@ -1357,10 +1368,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
err,
|
err,
|
||||||
self_source,
|
self_source,
|
||||||
args,
|
args,
|
||||||
trait_ref.instantiate(
|
trait_ref
|
||||||
self.tcx,
|
.instantiate(
|
||||||
self.fresh_args_for_item(sugg_span, impl_did)
|
self.tcx,
|
||||||
).with_self_ty(self.tcx, rcvr_ty),
|
self.fresh_args_for_item(sugg_span, impl_did),
|
||||||
|
)
|
||||||
|
.with_self_ty(self.tcx, rcvr_ty),
|
||||||
idx,
|
idx,
|
||||||
sugg_span,
|
sugg_span,
|
||||||
item,
|
item,
|
||||||
@ -1397,8 +1410,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
ty::TraitRef::new(
|
ty::TraitRef::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
trait_did,
|
trait_did,
|
||||||
self.fresh_args_for_item(sugg_span, trait_did)
|
self.fresh_args_for_item(sugg_span, trait_did),
|
||||||
).with_self_ty(self.tcx, rcvr_ty),
|
)
|
||||||
|
.with_self_ty(self.tcx, rcvr_ty),
|
||||||
idx,
|
idx,
|
||||||
sugg_span,
|
sugg_span,
|
||||||
item,
|
item,
|
||||||
@ -1409,7 +1423,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !suggs.is_empty() && let Some(span) = sugg_span {
|
if !suggs.is_empty()
|
||||||
|
&& let Some(span) = sugg_span
|
||||||
|
{
|
||||||
err.span_suggestions(
|
err.span_suggestions(
|
||||||
span.with_hi(item_name.span.lo()),
|
span.with_hi(item_name.span.lo()),
|
||||||
"use fully-qualified syntax to disambiguate",
|
"use fully-qualified syntax to disambiguate",
|
||||||
@ -1585,39 +1601,39 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
let mut applicability = Applicability::MachineApplicable;
|
let mut applicability = Applicability::MachineApplicable;
|
||||||
let args = if let SelfSource::MethodCall(receiver) = source
|
let args = if let SelfSource::MethodCall(receiver) = source
|
||||||
&& let Some(args) = args
|
&& let Some(args) = args
|
||||||
{
|
{
|
||||||
// The first arg is the same kind as the receiver
|
// The first arg is the same kind as the receiver
|
||||||
let explicit_args = if first_arg.is_some() {
|
let explicit_args = if first_arg.is_some() {
|
||||||
std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
|
std::iter::once(receiver).chain(args.iter()).collect::<Vec<_>>()
|
||||||
} else {
|
|
||||||
// There is no `Self` kind to infer the arguments from
|
|
||||||
if has_unsuggestable_args {
|
|
||||||
applicability = Applicability::HasPlaceholders;
|
|
||||||
}
|
|
||||||
args.iter().collect()
|
|
||||||
};
|
|
||||||
format!(
|
|
||||||
"({}{})",
|
|
||||||
first_arg.unwrap_or(""),
|
|
||||||
explicit_args
|
|
||||||
.iter()
|
|
||||||
.map(|arg| self
|
|
||||||
.tcx
|
|
||||||
.sess
|
|
||||||
.source_map()
|
|
||||||
.span_to_snippet(arg.span)
|
|
||||||
.unwrap_or_else(|_| {
|
|
||||||
applicability = Applicability::HasPlaceholders;
|
|
||||||
"_".to_owned()
|
|
||||||
}))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", "),
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
applicability = Applicability::HasPlaceholders;
|
// There is no `Self` kind to infer the arguments from
|
||||||
"(...)".to_owned()
|
if has_unsuggestable_args {
|
||||||
|
applicability = Applicability::HasPlaceholders;
|
||||||
|
}
|
||||||
|
args.iter().collect()
|
||||||
};
|
};
|
||||||
|
format!(
|
||||||
|
"({}{})",
|
||||||
|
first_arg.unwrap_or(""),
|
||||||
|
explicit_args
|
||||||
|
.iter()
|
||||||
|
.map(|arg| self
|
||||||
|
.tcx
|
||||||
|
.sess
|
||||||
|
.source_map()
|
||||||
|
.span_to_snippet(arg.span)
|
||||||
|
.unwrap_or_else(|_| {
|
||||||
|
applicability = Applicability::HasPlaceholders;
|
||||||
|
"_".to_owned()
|
||||||
|
}))
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", "),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
applicability = Applicability::HasPlaceholders;
|
||||||
|
"(...)".to_owned()
|
||||||
|
};
|
||||||
err.span_suggestion(
|
err.span_suggestion(
|
||||||
sugg_span,
|
sugg_span,
|
||||||
"use associated function syntax instead",
|
"use associated function syntax instead",
|
||||||
@ -3296,7 +3312,8 @@ fn print_disambiguation_help<'tcx>(
|
|||||||
{
|
{
|
||||||
let def_kind_descr = tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id);
|
let def_kind_descr = tcx.def_kind_descr(item.kind.as_def_kind(), item.def_id);
|
||||||
let item_name = item.ident(tcx);
|
let item_name = item.ident(tcx);
|
||||||
let rcvr_ref = tcx.fn_sig(item.def_id)
|
let rcvr_ref = tcx
|
||||||
|
.fn_sig(item.def_id)
|
||||||
.skip_binder()
|
.skip_binder()
|
||||||
.skip_binder()
|
.skip_binder()
|
||||||
.inputs()
|
.inputs()
|
||||||
|
@ -87,7 +87,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
|||||||
| (ty::Alias(ty::Projection, proj), ty::Param(p))
|
| (ty::Alias(ty::Projection, proj), ty::Param(p))
|
||||||
if !tcx.is_impl_trait_in_trait(proj.def_id) =>
|
if !tcx.is_impl_trait_in_trait(proj.def_id) =>
|
||||||
{
|
{
|
||||||
let parent = tcx.generics_of(body_owner_def_id)
|
let parent = tcx
|
||||||
|
.generics_of(body_owner_def_id)
|
||||||
.opt_type_param(p, tcx)
|
.opt_type_param(p, tcx)
|
||||||
.and_then(|param| {
|
.and_then(|param| {
|
||||||
let p_def_id = param.def_id;
|
let p_def_id = param.def_id;
|
||||||
|
@ -112,7 +112,9 @@ where
|
|||||||
};
|
};
|
||||||
|
|
||||||
for (idx, s) in args.iter().enumerate() {
|
for (idx, s) in args.iter().enumerate() {
|
||||||
if variances.map(|variances| variances[idx]) != Some(ty::Variance::Bivariant) {
|
if variances.map(|variances| variances[idx])
|
||||||
|
!= Some(ty::Variance::Bivariant)
|
||||||
|
{
|
||||||
s.visit_with(self)?;
|
s.visit_with(self)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -178,7 +178,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
|
|||||||
|
|
||||||
check_cfg.exhaustive_names = true;
|
check_cfg.exhaustive_names = true;
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if arg.is_word() && let Some(ident) = arg.ident() {
|
if arg.is_word()
|
||||||
|
&& let Some(ident) = arg.ident()
|
||||||
|
{
|
||||||
check_cfg.expecteds.entry(ident.name).or_insert(ExpectedValues::Any);
|
check_cfg.expecteds.entry(ident.name).or_insert(ExpectedValues::Any);
|
||||||
} else {
|
} else {
|
||||||
error!("`names()` arguments must be simple identifiers");
|
error!("`names()` arguments must be simple identifiers");
|
||||||
@ -188,7 +190,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
|
|||||||
set_old_syntax();
|
set_old_syntax();
|
||||||
|
|
||||||
if let Some((name, values)) = args.split_first() {
|
if let Some((name, values)) = args.split_first() {
|
||||||
if name.is_word() && let Some(ident) = name.ident() {
|
if name.is_word()
|
||||||
|
&& let Some(ident) = name.ident()
|
||||||
|
{
|
||||||
let expected_values = check_cfg
|
let expected_values = check_cfg
|
||||||
.expecteds
|
.expecteds
|
||||||
.entry(ident.name)
|
.entry(ident.name)
|
||||||
@ -236,12 +240,16 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
|
|||||||
let mut values_any_specified = false;
|
let mut values_any_specified = false;
|
||||||
|
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if arg.is_word() && let Some(ident) = arg.ident() {
|
if arg.is_word()
|
||||||
|
&& let Some(ident) = arg.ident()
|
||||||
|
{
|
||||||
if values_specified {
|
if values_specified {
|
||||||
error!("`cfg()` names cannot be after values");
|
error!("`cfg()` names cannot be after values");
|
||||||
}
|
}
|
||||||
names.push(ident);
|
names.push(ident);
|
||||||
} else if arg.has_name(sym::any) && let Some(args) = arg.meta_item_list() {
|
} else if arg.has_name(sym::any)
|
||||||
|
&& let Some(args) = arg.meta_item_list()
|
||||||
|
{
|
||||||
if any_specified {
|
if any_specified {
|
||||||
error!("`any()` cannot be specified multiple times");
|
error!("`any()` cannot be specified multiple times");
|
||||||
}
|
}
|
||||||
@ -249,7 +257,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
|
|||||||
if !args.is_empty() {
|
if !args.is_empty() {
|
||||||
error!("`any()` must be empty");
|
error!("`any()` must be empty");
|
||||||
}
|
}
|
||||||
} else if arg.has_name(sym::values) && let Some(args) = arg.meta_item_list() {
|
} else if arg.has_name(sym::values)
|
||||||
|
&& let Some(args) = arg.meta_item_list()
|
||||||
|
{
|
||||||
if names.is_empty() {
|
if names.is_empty() {
|
||||||
error!("`values()` cannot be specified before the names");
|
error!("`values()` cannot be specified before the names");
|
||||||
} else if values_specified {
|
} else if values_specified {
|
||||||
@ -260,7 +270,9 @@ pub(crate) fn parse_check_cfg(handler: &EarlyErrorHandler, specs: Vec<String>) -
|
|||||||
for arg in args {
|
for arg in args {
|
||||||
if let Some(LitKind::Str(s, _)) = arg.lit().map(|lit| &lit.kind) {
|
if let Some(LitKind::Str(s, _)) = arg.lit().map(|lit| &lit.kind) {
|
||||||
values.insert(Some(*s));
|
values.insert(Some(*s));
|
||||||
} else if arg.has_name(sym::any) && let Some(args) = arg.meta_item_list() {
|
} else if arg.has_name(sym::any)
|
||||||
|
&& let Some(args) = arg.meta_item_list()
|
||||||
|
{
|
||||||
if values_any_specified {
|
if values_any_specified {
|
||||||
error!("`any()` in `values()` cannot be specified multiple times");
|
error!("`any()` in `values()` cannot be specified multiple times");
|
||||||
}
|
}
|
||||||
|
@ -415,7 +415,9 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<C
|
|||||||
let mut base = session.opts.crate_types.clone();
|
let mut base = session.opts.crate_types.clone();
|
||||||
if base.is_empty() {
|
if base.is_empty() {
|
||||||
let attr_types = attrs.iter().filter_map(|a| {
|
let attr_types = attrs.iter().filter_map(|a| {
|
||||||
if a.has_name(sym::crate_type) && let Some(s) = a.value_str() {
|
if a.has_name(sym::crate_type)
|
||||||
|
&& let Some(s) = a.value_str()
|
||||||
|
{
|
||||||
categorize_crate_type(s)
|
categorize_crate_type(s)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -85,7 +85,9 @@ impl Parse for Value {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Expr::Macro(expr) => {
|
Expr::Macro(expr) => {
|
||||||
if expr.mac.path.is_ident("env") && let Ok(lit) = expr.mac.parse_body() {
|
if expr.mac.path.is_ident("env")
|
||||||
|
&& let Ok(lit) = expr.mac.parse_body()
|
||||||
|
{
|
||||||
return Ok(Value::Env(lit, expr.mac.clone()));
|
return Ok(Value::Env(lit, expr.mac.clone()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2396,8 +2396,10 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String {
|
|||||||
// * character escapes
|
// * character escapes
|
||||||
//
|
//
|
||||||
// FIXME: This passes through `-/*spacer*/0` verbatim.
|
// FIXME: This passes through `-/*spacer*/0` verbatim.
|
||||||
Literal if !value.span.from_expansion()
|
Literal
|
||||||
&& let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) => {
|
if !value.span.from_expansion()
|
||||||
|
&& let Ok(snippet) = tcx.sess.source_map().span_to_snippet(value.span) =>
|
||||||
|
{
|
||||||
snippet
|
snippet
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2408,10 +2410,12 @@ pub fn rendered_const<'tcx>(tcx: TyCtxt<'tcx>, body: hir::BodyId) -> String {
|
|||||||
// FIXME: Omit the curly braces if the enclosing expression is an array literal
|
// FIXME: Omit the curly braces if the enclosing expression is an array literal
|
||||||
// with a repeated element (an `ExprKind::Repeat`) as in such case it
|
// with a repeated element (an `ExprKind::Repeat`) as in such case it
|
||||||
// would not actually need any disambiguation.
|
// would not actually need any disambiguation.
|
||||||
Complex => if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst {
|
Complex => {
|
||||||
"{ _ }".to_owned()
|
if tcx.def_kind(hir.body_owner_def_id(body).to_def_id()) == DefKind::AnonConst {
|
||||||
} else {
|
"{ _ }".to_owned()
|
||||||
"_".to_owned()
|
} else {
|
||||||
|
"_".to_owned()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -507,11 +507,7 @@ fn write_span<W>(
|
|||||||
where
|
where
|
||||||
W: Write,
|
W: Write,
|
||||||
{
|
{
|
||||||
let maybe_alt_class = if layer > 0 {
|
let maybe_alt_class = if layer > 0 { if alt { " odd" } else { " even" } } else { "" };
|
||||||
if alt { " odd" } else { " even" }
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
let maybe_title_attr = if !tooltip.is_empty() {
|
let maybe_title_attr = if !tooltip.is_empty() {
|
||||||
format!(" title=\"{}\"", escape_attr(tooltip))
|
format!(" title=\"{}\"", escape_attr(tooltip))
|
||||||
} else {
|
} else {
|
||||||
|
@ -28,7 +28,9 @@ impl SwitchTargets {
|
|||||||
|
|
||||||
/// Inverse of `SwitchTargets::static_if`.
|
/// Inverse of `SwitchTargets::static_if`.
|
||||||
pub fn as_static_if(&self) -> Option<(u128, BasicBlock, BasicBlock)> {
|
pub fn as_static_if(&self) -> Option<(u128, BasicBlock, BasicBlock)> {
|
||||||
if let &[value] = &self.values[..] && let &[then, else_] = &self.targets[..] {
|
if let &[value] = &self.values[..]
|
||||||
|
&& let &[then, else_] = &self.targets[..]
|
||||||
|
{
|
||||||
Some((value, then, else_))
|
Some((value, then, else_))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -655,7 +655,9 @@ impl<'tcx> Pat<'tcx> {
|
|||||||
pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> {
|
pub fn pat_error_reported(&self) -> Result<(), ErrorGuaranteed> {
|
||||||
let mut error = None;
|
let mut error = None;
|
||||||
self.walk(|pat| {
|
self.walk(|pat| {
|
||||||
if let PatKind::Error(e) = pat.kind && error.is_none() {
|
if let PatKind::Error(e) = pat.kind
|
||||||
|
&& error.is_none()
|
||||||
|
{
|
||||||
error = Some(e);
|
error = Some(e);
|
||||||
}
|
}
|
||||||
error.is_none()
|
error.is_none()
|
||||||
|
@ -192,10 +192,10 @@ impl<'tcx> Cx<'tcx> {
|
|||||||
cast: PointerCoercion::ArrayToPointer,
|
cast: PointerCoercion::ArrayToPointer,
|
||||||
}
|
}
|
||||||
} else if let hir::ExprKind::Path(ref qpath) = source.kind
|
} else if let hir::ExprKind::Path(ref qpath) = source.kind
|
||||||
&& let res = self.typeck_results().qpath_res(qpath, source.hir_id)
|
&& let res = self.typeck_results().qpath_res(qpath, source.hir_id)
|
||||||
&& let ty = self.typeck_results().node_type(source.hir_id)
|
&& let ty = self.typeck_results().node_type(source.hir_id)
|
||||||
&& let ty::Adt(adt_def, args) = ty.kind()
|
&& let ty::Adt(adt_def, args) = ty.kind()
|
||||||
&& let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
|
&& let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Const), variant_ctor_id) = res
|
||||||
{
|
{
|
||||||
// Check whether this is casting an enum variant discriminant.
|
// Check whether this is casting an enum variant discriminant.
|
||||||
// To prevent cycles, we refer to the discriminant initializer,
|
// To prevent cycles, we refer to the discriminant initializer,
|
||||||
|
@ -200,7 +200,9 @@ impl<'tcx> ConstToPat<'tcx> {
|
|||||||
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
// We errored. Signal that in the pattern, so that follow up errors can be silenced.
|
||||||
let kind = PatKind::Error(e);
|
let kind = PatKind::Error(e);
|
||||||
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
|
return Box::new(Pat { span: self.span, ty: cv.ty(), kind });
|
||||||
} else if let ty::Adt(..) = cv.ty().kind() && matches!(cv, mir::Const::Val(..)) {
|
} else if let ty::Adt(..) = cv.ty().kind()
|
||||||
|
&& matches!(cv, mir::Const::Val(..))
|
||||||
|
{
|
||||||
// This branch is only entered when the current `cv` is `mir::Const::Val`.
|
// This branch is only entered when the current `cv` is `mir::Const::Val`.
|
||||||
// This is because `mir::Const::ty` has already been handled by `Self::recur`
|
// This is because `mir::Const::ty` has already been handled by `Self::recur`
|
||||||
// and the invalid types may be ignored.
|
// and the invalid types may be ignored.
|
||||||
|
@ -69,7 +69,9 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
|
TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
|
||||||
let fn_ty = self.instantiate_ty(f.const_.ty());
|
let fn_ty = self.instantiate_ty(f.const_.ty());
|
||||||
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
|
self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind()
|
||||||
|
&& tcx.is_intrinsic(def_id)
|
||||||
|
{
|
||||||
// Don't give intrinsics the extra penalty for calls
|
// Don't give intrinsics the extra penalty for calls
|
||||||
INSTR_COST
|
INSTR_COST
|
||||||
} else {
|
} else {
|
||||||
|
@ -138,7 +138,9 @@ impl CoverageCounters {
|
|||||||
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
|
// If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also
|
||||||
// have an expression (to be injected into an existing `BasicBlock` represented by this
|
// have an expression (to be injected into an existing `BasicBlock` represented by this
|
||||||
// `BasicCoverageBlock`).
|
// `BasicCoverageBlock`).
|
||||||
if let Some(node_counter) = self.bcb_counter(to_bcb) && !node_counter.is_expression() {
|
if let Some(node_counter) = self.bcb_counter(to_bcb)
|
||||||
|
&& !node_counter.is_expression()
|
||||||
|
{
|
||||||
bug!(
|
bug!(
|
||||||
"attempt to add an incoming edge counter from {from_bcb:?} \
|
"attempt to add an incoming edge counter from {from_bcb:?} \
|
||||||
when the target BCB already has {node_counter:?}"
|
when the target BCB already has {node_counter:?}"
|
||||||
|
@ -475,7 +475,9 @@ impl<'a> CoverageSpansGenerator<'a> {
|
|||||||
}
|
}
|
||||||
while let Some(curr) = self.sorted_spans_iter.next() {
|
while let Some(curr) = self.sorted_spans_iter.next() {
|
||||||
debug!("FOR curr={:?}", curr);
|
debug!("FOR curr={:?}", curr);
|
||||||
if let Some(prev) = &self.some_prev && prev.span.lo() > curr.span.lo() {
|
if let Some(prev) = &self.some_prev
|
||||||
|
&& prev.span.lo() > curr.span.lo()
|
||||||
|
{
|
||||||
// Skip curr because prev has already advanced beyond the end of curr.
|
// Skip curr because prev has already advanced beyond the end of curr.
|
||||||
// This can only happen if a prior iteration updated `prev` to skip past
|
// This can only happen if a prior iteration updated `prev` to skip past
|
||||||
// a region of code, such as skipping past a closure.
|
// a region of code, such as skipping past a closure.
|
||||||
|
@ -597,7 +597,9 @@ fn propagatable_scalar(
|
|||||||
state: &State<FlatSet<Scalar>>,
|
state: &State<FlatSet<Scalar>>,
|
||||||
map: &Map,
|
map: &Map,
|
||||||
) -> Option<Scalar> {
|
) -> Option<Scalar> {
|
||||||
if let FlatSet::Elem(value) = state.get_idx(place, map) && value.try_to_int().is_ok() {
|
if let FlatSet::Elem(value) = state.get_idx(place, map)
|
||||||
|
&& value.try_to_int().is_ok()
|
||||||
|
{
|
||||||
// Do not attempt to propagate pointers, as we may fail to preserve their identity.
|
// Do not attempt to propagate pointers, as we may fail to preserve their identity.
|
||||||
Some(value)
|
Some(value)
|
||||||
} else {
|
} else {
|
||||||
@ -836,7 +838,8 @@ impl<'tcx> Visitor<'tcx> for OperandCollector<'tcx, '_, '_, '_> {
|
|||||||
location: Location,
|
location: Location,
|
||||||
) {
|
) {
|
||||||
if let PlaceElem::Index(local) = elem
|
if let PlaceElem::Index(local) = elem
|
||||||
&& let Some(value) = self.visitor.try_make_constant(self.ecx, local.into(), self.state, self.map)
|
&& let Some(value) =
|
||||||
|
self.visitor.try_make_constant(self.ecx, local.into(), self.state, self.map)
|
||||||
{
|
{
|
||||||
self.visitor.patch.before_effect.insert((location, local.into()), value);
|
self.visitor.patch.before_effect.insert((location, local.into()), value);
|
||||||
}
|
}
|
||||||
|
@ -461,7 +461,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||||||
}
|
}
|
||||||
NullaryOp(null_op, ty) => {
|
NullaryOp(null_op, ty) => {
|
||||||
let layout = self.ecx.layout_of(ty).ok()?;
|
let layout = self.ecx.layout_of(ty).ok()?;
|
||||||
if let NullOp::SizeOf | NullOp::AlignOf = null_op && layout.is_unsized() {
|
if let NullOp::SizeOf | NullOp::AlignOf = null_op
|
||||||
|
&& layout.is_unsized()
|
||||||
|
{
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let val = match null_op {
|
let val = match null_op {
|
||||||
@ -865,7 +867,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
|
|||||||
.collect();
|
.collect();
|
||||||
let fields = fields?;
|
let fields = fields?;
|
||||||
|
|
||||||
if let AggregateTy::Array = ty && fields.len() > 4 {
|
if let AggregateTy::Array = ty
|
||||||
|
&& fields.len() > 4
|
||||||
|
{
|
||||||
let first = fields[0];
|
let first = fields[0];
|
||||||
if fields.iter().all(|&v| v == first) {
|
if fields.iter().all(|&v| v == first) {
|
||||||
let len = ty::Const::from_target_usize(self.tcx, fields.len().try_into().unwrap());
|
let len = ty::Const::from_target_usize(self.tcx, fields.len().try_into().unwrap());
|
||||||
@ -1008,8 +1012,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
|
|||||||
// Do not try to simplify a constant, it's already in canonical shape.
|
// Do not try to simplify a constant, it's already in canonical shape.
|
||||||
&& !matches!(rvalue, Rvalue::Use(Operand::Constant(_)))
|
&& !matches!(rvalue, Rvalue::Use(Operand::Constant(_)))
|
||||||
{
|
{
|
||||||
if let Some(value) = self.simplify_rvalue(rvalue, location)
|
if let Some(value) = self.simplify_rvalue(rvalue, location) {
|
||||||
{
|
|
||||||
if let Some(const_) = self.try_as_constant(value) {
|
if let Some(const_) = self.try_as_constant(value) {
|
||||||
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
|
*rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
|
||||||
} else if let Some(local) = self.try_as_local(value, location)
|
} else if let Some(local) = self.try_as_local(value, location)
|
||||||
|
@ -247,7 +247,9 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
|
|||||||
let last_non_rec = self.opportunities.len();
|
let last_non_rec = self.opportunities.len();
|
||||||
|
|
||||||
let predecessors = &self.body.basic_blocks.predecessors()[bb];
|
let predecessors = &self.body.basic_blocks.predecessors()[bb];
|
||||||
if let &[pred] = &predecessors[..] && bb != START_BLOCK {
|
if let &[pred] = &predecessors[..]
|
||||||
|
&& bb != START_BLOCK
|
||||||
|
{
|
||||||
let term = self.body.basic_blocks[pred].terminator();
|
let term = self.body.basic_blocks[pred].terminator();
|
||||||
match term.kind {
|
match term.kind {
|
||||||
TerminatorKind::SwitchInt { ref discr, ref targets } => {
|
TerminatorKind::SwitchInt { ref discr, ref targets } => {
|
||||||
@ -419,8 +421,10 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
|
|||||||
// Do not support unions.
|
// Do not support unions.
|
||||||
AggregateKind::Adt(.., Some(_)) => return None,
|
AggregateKind::Adt(.., Some(_)) => return None,
|
||||||
AggregateKind::Adt(_, variant_index, ..) if agg_ty.is_enum() => {
|
AggregateKind::Adt(_, variant_index, ..) if agg_ty.is_enum() => {
|
||||||
if let Some(discr_target) = self.map.apply(lhs, TrackElem::Discriminant)
|
if let Some(discr_target) =
|
||||||
&& let Some(discr_value) = discriminant_for_variant(agg_ty, *variant_index)
|
self.map.apply(lhs, TrackElem::Discriminant)
|
||||||
|
&& let Some(discr_value) =
|
||||||
|
discriminant_for_variant(agg_ty, *variant_index)
|
||||||
{
|
{
|
||||||
self.process_operand(bb, discr_target, &discr_value, state);
|
self.process_operand(bb, discr_target, &discr_value, state);
|
||||||
}
|
}
|
||||||
|
@ -506,7 +506,9 @@ impl<'a> Parser<'a> {
|
|||||||
if expected.contains(&TokenType::Token(token::Semi)) {
|
if expected.contains(&TokenType::Token(token::Semi)) {
|
||||||
// If the user is trying to write a ternary expression, recover it and
|
// If the user is trying to write a ternary expression, recover it and
|
||||||
// return an Err to prevent a cascade of irrelevant diagnostics
|
// return an Err to prevent a cascade of irrelevant diagnostics
|
||||||
if self.prev_token == token::Question && let Err(e) = self.maybe_recover_from_ternary_operator() {
|
if self.prev_token == token::Question
|
||||||
|
&& let Err(e) = self.maybe_recover_from_ternary_operator()
|
||||||
|
{
|
||||||
return Err(e);
|
return Err(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,15 +107,15 @@ macro_rules! maybe_whole {
|
|||||||
macro_rules! maybe_recover_from_interpolated_ty_qpath {
|
macro_rules! maybe_recover_from_interpolated_ty_qpath {
|
||||||
($self: expr, $allow_qpath_recovery: expr) => {
|
($self: expr, $allow_qpath_recovery: expr) => {
|
||||||
if $allow_qpath_recovery
|
if $allow_qpath_recovery
|
||||||
&& $self.may_recover()
|
&& $self.may_recover()
|
||||||
&& $self.look_ahead(1, |t| t == &token::ModSep)
|
&& $self.look_ahead(1, |t| t == &token::ModSep)
|
||||||
&& let token::Interpolated(nt) = &$self.token.kind
|
&& let token::Interpolated(nt) = &$self.token.kind
|
||||||
&& let token::NtTy(ty) = &**nt
|
&& let token::NtTy(ty) = &**nt
|
||||||
{
|
{
|
||||||
let ty = ty.clone();
|
let ty = ty.clone();
|
||||||
$self.bump();
|
$self.bump();
|
||||||
return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty);
|
return $self.maybe_recover_from_bad_qpath_stage_2($self.prev_token.span, ty);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,7 +196,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some((depr, span)) = &depr && depr.is_since_rustc_version() && stab.is_none() {
|
if let Some((depr, span)) = &depr
|
||||||
|
&& depr.is_since_rustc_version()
|
||||||
|
&& stab.is_none()
|
||||||
|
{
|
||||||
self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span });
|
self.tcx.sess.emit_err(errors::DeprecatedAttribute { span: *span });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,11 +187,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
if let Some(kind) = self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id)
|
if let Some(kind) = self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id)
|
||||||
&& let ty::Tuple(args) = trait_ref.args.type_at(1).kind()
|
&& let ty::Tuple(args) = trait_ref.args.type_at(1).kind()
|
||||||
{
|
{
|
||||||
let args = args
|
let args = args.iter().map(|ty| ty.to_string()).collect::<Vec<_>>().join(", ");
|
||||||
.iter()
|
|
||||||
.map(|ty| ty.to_string())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join(", ");
|
|
||||||
flags.push((sym::Trait, Some(format!("{}({args})", kind.as_str()))));
|
flags.push((sym::Trait, Some(format!("{}({args})", kind.as_str()))));
|
||||||
} else {
|
} else {
|
||||||
flags.push((sym::Trait, Some(trait_ref.print_only_trait_path().to_string())));
|
flags.push((sym::Trait, Some(trait_ref.print_only_trait_path().to_string())));
|
||||||
@ -636,7 +632,9 @@ impl<'tcx> OnUnimplementedDirective {
|
|||||||
let value = cfg.value.map(|v| {
|
let value = cfg.value.map(|v| {
|
||||||
// `with_no_visible_paths` is also used when generating the options,
|
// `with_no_visible_paths` is also used when generating the options,
|
||||||
// so we need to match it here.
|
// so we need to match it here.
|
||||||
ty::print::with_no_visible_paths!(OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map))
|
ty::print::with_no_visible_paths!(
|
||||||
|
OnUnimplementedFormatString(v).format(tcx, trait_ref, &options_map)
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
options.contains(&(cfg.name, value))
|
options.contains(&(cfg.name, value))
|
||||||
|
@ -2723,11 +2723,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if !impls.is_empty() {
|
if !impls.is_empty() {
|
||||||
let len = impls.len();
|
let len = impls.len();
|
||||||
let mut types = impls.iter()
|
let mut types = impls
|
||||||
.map(|t| with_no_trimmed_paths!(format!(
|
.iter()
|
||||||
" {}",
|
.map(|t| {
|
||||||
tcx.type_of(*t).instantiate_identity(),
|
with_no_trimmed_paths!(format!(
|
||||||
)))
|
" {}",
|
||||||
|
tcx.type_of(*t).instantiate_identity(),
|
||||||
|
))
|
||||||
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let post = if types.len() > 9 {
|
let post = if types.len() > 9 {
|
||||||
types.truncate(8);
|
types.truncate(8);
|
||||||
@ -2769,30 +2772,47 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ObligationCauseCode::RepeatElementCopy { is_constable, elt_type, elt_span, elt_stmt_span } => {
|
ObligationCauseCode::RepeatElementCopy {
|
||||||
|
is_constable,
|
||||||
|
elt_type,
|
||||||
|
elt_span,
|
||||||
|
elt_stmt_span,
|
||||||
|
} => {
|
||||||
err.note(
|
err.note(
|
||||||
"the `Copy` trait is required because this value will be copied for each element of the array",
|
"the `Copy` trait is required because this value will be copied for each element of the array",
|
||||||
);
|
);
|
||||||
let value_kind = match is_constable {
|
let value_kind = match is_constable {
|
||||||
IsConstable::Fn => Some("the result of the function call"),
|
IsConstable::Fn => Some("the result of the function call"),
|
||||||
IsConstable::Ctor => Some("the result of the constructor"),
|
IsConstable::Ctor => Some("the result of the constructor"),
|
||||||
_ => None
|
_ => None,
|
||||||
};
|
};
|
||||||
let sm = tcx.sess.source_map();
|
let sm = tcx.sess.source_map();
|
||||||
if let Some(value_kind) = value_kind &&
|
if let Some(value_kind) = value_kind
|
||||||
let Ok(snip) = sm.span_to_snippet(elt_span)
|
&& let Ok(snip) = sm.span_to_snippet(elt_span)
|
||||||
{
|
{
|
||||||
let help_msg = format!(
|
let help_msg = format!(
|
||||||
"consider creating a new `const` item and initializing it with {value_kind} \
|
"consider creating a new `const` item and initializing it with {value_kind} \
|
||||||
to be used in the repeat position");
|
to be used in the repeat position"
|
||||||
|
);
|
||||||
let indentation = sm.indentation_before(elt_stmt_span).unwrap_or_default();
|
let indentation = sm.indentation_before(elt_stmt_span).unwrap_or_default();
|
||||||
err.multipart_suggestion(help_msg, vec![
|
err.multipart_suggestion(
|
||||||
(elt_stmt_span.shrink_to_lo(), format!("const ARRAY_REPEAT_VALUE: {elt_type} = {snip};\n{indentation}")),
|
help_msg,
|
||||||
(elt_span, "ARRAY_REPEAT_VALUE".to_string())
|
vec![
|
||||||
], Applicability::MachineApplicable);
|
(
|
||||||
|
elt_stmt_span.shrink_to_lo(),
|
||||||
|
format!(
|
||||||
|
"const ARRAY_REPEAT_VALUE: {elt_type} = {snip};\n{indentation}"
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(elt_span, "ARRAY_REPEAT_VALUE".to_string()),
|
||||||
|
],
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.tcx.sess.is_nightly_build() && matches!(is_constable, IsConstable::Fn|IsConstable::Ctor) {
|
if self.tcx.sess.is_nightly_build()
|
||||||
|
&& matches!(is_constable, IsConstable::Fn | IsConstable::Ctor)
|
||||||
|
{
|
||||||
err.help(
|
err.help(
|
||||||
"create an inline `const` block, see RFC #2920 \
|
"create an inline `const` block, see RFC #2920 \
|
||||||
<https://github.com/rust-lang/rfcs/pull/2920> for more information",
|
<https://github.com/rust-lang/rfcs/pull/2920> for more information",
|
||||||
@ -2957,7 +2977,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
ObligationCauseCode::SizedCoroutineInterior(coroutine_def_id) => {
|
ObligationCauseCode::SizedCoroutineInterior(coroutine_def_id) => {
|
||||||
let what = match self.tcx.coroutine_kind(coroutine_def_id) {
|
let what = match self.tcx.coroutine_kind(coroutine_def_id) {
|
||||||
None | Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Gen(_)) => "yield",
|
None
|
||||||
|
| Some(hir::CoroutineKind::Coroutine)
|
||||||
|
| Some(hir::CoroutineKind::Gen(_)) => "yield",
|
||||||
Some(hir::CoroutineKind::Async(..)) => "await",
|
Some(hir::CoroutineKind::Async(..)) => "await",
|
||||||
};
|
};
|
||||||
err.note(format!(
|
err.note(format!(
|
||||||
@ -3519,7 +3541,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
{
|
{
|
||||||
if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
|
if let hir::Expr { kind: hir::ExprKind::Block(block, _), .. } = expr {
|
||||||
let inner_expr = expr.peel_blocks();
|
let inner_expr = expr.peel_blocks();
|
||||||
let ty = typeck_results.expr_ty_adjusted_opt(inner_expr)
|
let ty = typeck_results
|
||||||
|
.expr_ty_adjusted_opt(inner_expr)
|
||||||
.unwrap_or(Ty::new_misc_error(tcx));
|
.unwrap_or(Ty::new_misc_error(tcx));
|
||||||
let span = inner_expr.span;
|
let span = inner_expr.span;
|
||||||
if Some(span) != err.span.primary_span() {
|
if Some(span) != err.span.primary_span() {
|
||||||
@ -3538,14 +3561,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
tcx.lang_items().fn_once_trait(),
|
tcx.lang_items().fn_once_trait(),
|
||||||
tcx.lang_items().fn_mut_trait(),
|
tcx.lang_items().fn_mut_trait(),
|
||||||
tcx.lang_items().fn_trait(),
|
tcx.lang_items().fn_trait(),
|
||||||
].contains(&Some(pred.def_id()))
|
]
|
||||||
|
.contains(&Some(pred.def_id()))
|
||||||
{
|
{
|
||||||
if let [stmt, ..] = block.stmts
|
if let [stmt, ..] = block.stmts
|
||||||
&& let hir::StmtKind::Semi(value) = stmt.kind
|
&& let hir::StmtKind::Semi(value) = stmt.kind
|
||||||
&& let hir::ExprKind::Closure(hir::Closure {
|
&& let hir::ExprKind::Closure(hir::Closure {
|
||||||
body,
|
body, fn_decl_span, ..
|
||||||
fn_decl_span,
|
|
||||||
..
|
|
||||||
}) = value.kind
|
}) = value.kind
|
||||||
&& let body = hir.body(*body)
|
&& let body = hir.body(*body)
|
||||||
&& !matches!(body.value.kind, hir::ExprKind::Block(..))
|
&& !matches!(body.value.kind, hir::ExprKind::Block(..))
|
||||||
@ -3568,9 +3590,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
"you might have meant to create the closure instead of a block",
|
"you might have meant to create the closure instead of a block",
|
||||||
format!(
|
format!(
|
||||||
"|{}| ",
|
"|{}| ",
|
||||||
(0..pred.trait_ref.args.len() - 1).map(|_| "_")
|
(0..pred.trait_ref.args.len() - 1)
|
||||||
|
.map(|_| "_")
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.join(", ")),
|
.join(", ")
|
||||||
|
),
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -928,10 +928,8 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool {
|
fn fn_arg_obligation(&self, obligation: &PredicateObligation<'tcx>) -> bool {
|
||||||
if let ObligationCauseCode::FunctionArgumentObligation {
|
if let ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
|
||||||
arg_hir_id,
|
obligation.cause.code()
|
||||||
..
|
|
||||||
} = obligation.cause.code()
|
|
||||||
&& let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id)
|
&& let Some(Node::Expr(arg)) = self.tcx.hir().find(*arg_hir_id)
|
||||||
&& let arg = arg.peel_borrows()
|
&& let arg = arg.peel_borrows()
|
||||||
&& let hir::ExprKind::Path(hir::QPath::Resolved(
|
&& let hir::ExprKind::Path(hir::QPath::Resolved(
|
||||||
|
@ -203,11 +203,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ImplTraitInTraitFinder<'_, 'tcx> {
|
|||||||
"we shouldn't walk non-predicate binders with `impl Trait`...",
|
"we shouldn't walk non-predicate binders with `impl Trait`...",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
ty::Region::new_bound(
|
ty::Region::new_bound(self.tcx, index.shifted_out_to_binder(self.depth), bv)
|
||||||
self.tcx,
|
|
||||||
index.shifted_out_to_binder(self.depth),
|
|
||||||
bv,
|
|
||||||
)
|
|
||||||
} else {
|
} else {
|
||||||
re
|
re
|
||||||
}
|
}
|
||||||
|
@ -285,9 +285,7 @@ impl<T, A: Allocator> Iterator for IntoIter<T, A> {
|
|||||||
// Also note the implementation of `Self: TrustedRandomAccess` requires
|
// Also note the implementation of `Self: TrustedRandomAccess` requires
|
||||||
// that `T: Copy` so reading elements from the buffer doesn't invalidate
|
// that `T: Copy` so reading elements from the buffer doesn't invalidate
|
||||||
// them for `Drop`.
|
// them for `Drop`.
|
||||||
unsafe {
|
unsafe { if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } }
|
||||||
if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,12 +21,16 @@ pub(crate) fn escape_ascii_into(output: &mut [ascii::Char; 4], byte: u8) -> Rang
|
|||||||
b'\\' => backslash(ascii::Char::ReverseSolidus),
|
b'\\' => backslash(ascii::Char::ReverseSolidus),
|
||||||
b'\'' => backslash(ascii::Char::Apostrophe),
|
b'\'' => backslash(ascii::Char::Apostrophe),
|
||||||
b'\"' => backslash(ascii::Char::QuotationMark),
|
b'\"' => backslash(ascii::Char::QuotationMark),
|
||||||
_ => if let Some(a) = byte.as_ascii() && !byte.is_ascii_control() {
|
_ => {
|
||||||
([a, ascii::Char::Null, ascii::Char::Null, ascii::Char::Null], 1)
|
if let Some(a) = byte.as_ascii()
|
||||||
} else {
|
&& !byte.is_ascii_control()
|
||||||
let hi = HEX_DIGITS[usize::from(byte >> 4)];
|
{
|
||||||
let lo = HEX_DIGITS[usize::from(byte & 0xf)];
|
([a, ascii::Char::Null, ascii::Char::Null, ascii::Char::Null], 1)
|
||||||
([ascii::Char::ReverseSolidus, ascii::Char::SmallX, hi, lo], 4)
|
} else {
|
||||||
|
let hi = HEX_DIGITS[usize::from(byte >> 4)];
|
||||||
|
let lo = HEX_DIGITS[usize::from(byte & 0xf)];
|
||||||
|
([ascii::Char::ReverseSolidus, ascii::Char::SmallX, hi, lo], 4)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
*output = data;
|
*output = data;
|
||||||
|
@ -83,11 +83,7 @@ where
|
|||||||
// last element. Used in the `DoubleEndedIterator` implementation.
|
// last element. Used in the `DoubleEndedIterator` implementation.
|
||||||
fn next_back_index(&self) -> usize {
|
fn next_back_index(&self) -> usize {
|
||||||
let rem = self.iter.len() % (self.step + 1);
|
let rem = self.iter.len() % (self.step + 1);
|
||||||
if self.first_take {
|
if self.first_take { if rem == 0 { self.step } else { rem - 1 } } else { rem }
|
||||||
if rem == 0 { self.step } else { rem - 1 }
|
|
||||||
} else {
|
|
||||||
rem
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -691,10 +691,7 @@ impl<T> MaybeUninit<T> {
|
|||||||
/// // they both get dropped!
|
/// // they both get dropped!
|
||||||
/// ```
|
/// ```
|
||||||
#[stable(feature = "maybe_uninit_extra", since = "1.60.0")]
|
#[stable(feature = "maybe_uninit_extra", since = "1.60.0")]
|
||||||
#[rustc_const_stable(
|
#[rustc_const_stable(feature = "const_maybe_uninit_assume_init_read", since = "1.75.0")]
|
||||||
feature = "const_maybe_uninit_assume_init_read",
|
|
||||||
since = "1.75.0"
|
|
||||||
)]
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
#[track_caller]
|
#[track_caller]
|
||||||
pub const unsafe fn assume_init_read(&self) -> T {
|
pub const unsafe fn assume_init_read(&self) -> T {
|
||||||
|
@ -1300,13 +1300,17 @@ impl File {
|
|||||||
|
|
||||||
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
|
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
|
||||||
#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
|
#[cfg(not(any(target_os = "redox", target_os = "espidf", target_os = "horizon")))]
|
||||||
let to_timespec = |time: Option<SystemTime>| {
|
let to_timespec = |time: Option<SystemTime>| match time {
|
||||||
match time {
|
Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
|
||||||
Some(time) if let Some(ts) = time.t.to_timespec() => Ok(ts),
|
Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(
|
||||||
Some(time) if time > crate::sys::time::UNIX_EPOCH => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
|
io::ErrorKind::InvalidInput,
|
||||||
Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too small to set as a file time")),
|
"timestamp is too large to set as a file time"
|
||||||
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
|
)),
|
||||||
}
|
Some(_) => Err(io::const_io_error!(
|
||||||
|
io::ErrorKind::InvalidInput,
|
||||||
|
"timestamp is too small to set as a file time"
|
||||||
|
)),
|
||||||
|
None => Ok(libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT as _ }),
|
||||||
};
|
};
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
|
if #[cfg(any(target_os = "redox", target_os = "espidf", target_os = "horizon"))] {
|
||||||
|
@ -274,15 +274,19 @@ pub fn current_exe() -> io::Result<PathBuf> {
|
|||||||
return path.canonicalize();
|
return path.canonicalize();
|
||||||
}
|
}
|
||||||
// Search PWD to infer current_exe.
|
// Search PWD to infer current_exe.
|
||||||
if let Some(pstr) = path.to_str() && pstr.contains("/") {
|
if let Some(pstr) = path.to_str()
|
||||||
|
&& pstr.contains("/")
|
||||||
|
{
|
||||||
return getcwd().map(|cwd| cwd.join(path))?.canonicalize();
|
return getcwd().map(|cwd| cwd.join(path))?.canonicalize();
|
||||||
}
|
}
|
||||||
// Search PATH to infer current_exe.
|
// Search PATH to infer current_exe.
|
||||||
if let Some(p) = getenv(OsStr::from_bytes("PATH".as_bytes())) {
|
if let Some(p) = getenv(OsStr::from_bytes("PATH".as_bytes())) {
|
||||||
for search_path in split_paths(&p) {
|
for search_path in split_paths(&p) {
|
||||||
let pb = search_path.join(&path);
|
let pb = search_path.join(&path);
|
||||||
if pb.is_file() && let Ok(metadata) = crate::fs::metadata(&pb) &&
|
if pb.is_file()
|
||||||
metadata.permissions().mode() & 0o111 != 0 {
|
&& let Ok(metadata) = crate::fs::metadata(&pb)
|
||||||
|
&& metadata.permissions().mode() & 0o111 != 0
|
||||||
|
{
|
||||||
return pb.canonicalize();
|
return pb.canonicalize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,12 +477,13 @@ impl File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
|
pub fn set_times(&self, times: FileTimes) -> io::Result<()> {
|
||||||
let to_timestamp = |time: Option<SystemTime>| {
|
let to_timestamp = |time: Option<SystemTime>| match time {
|
||||||
match time {
|
Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
|
||||||
Some(time) if let Some(ts) = time.to_wasi_timestamp() => Ok(ts),
|
Some(_) => Err(io::const_io_error!(
|
||||||
Some(_) => Err(io::const_io_error!(io::ErrorKind::InvalidInput, "timestamp is too large to set as a file time")),
|
io::ErrorKind::InvalidInput,
|
||||||
None => Ok(0),
|
"timestamp is too large to set as a file time"
|
||||||
}
|
)),
|
||||||
|
None => Ok(0),
|
||||||
};
|
};
|
||||||
self.fd.filestat_set_times(
|
self.fd.filestat_set_times(
|
||||||
to_timestamp(times.accessed)?,
|
to_timestamp(times.accessed)?,
|
||||||
|
@ -104,7 +104,9 @@ pub fn parse_prefix(path: &OsStr) -> Option<Prefix<'_>> {
|
|||||||
|
|
||||||
// The meaning of verbatim paths can change when they use a different
|
// The meaning of verbatim paths can change when they use a different
|
||||||
// separator.
|
// separator.
|
||||||
if let Some(parser) = parser.strip_prefix(r"?\") && !parser.prefix_bytes().iter().any(|&x| x == b'/') {
|
if let Some(parser) = parser.strip_prefix(r"?\")
|
||||||
|
&& !parser.prefix_bytes().iter().any(|&x| x == b'/')
|
||||||
|
{
|
||||||
// \\?\
|
// \\?\
|
||||||
if let Some(parser) = parser.strip_prefix(r"UNC\") {
|
if let Some(parser) = parser.strip_prefix(r"UNC\") {
|
||||||
// \\?\UNC\server\share
|
// \\?\UNC\server\share
|
||||||
|
@ -128,7 +128,8 @@ impl Once {
|
|||||||
RUNNING | QUEUED => {
|
RUNNING | QUEUED => {
|
||||||
// Set the state to QUEUED if it is not already.
|
// Set the state to QUEUED if it is not already.
|
||||||
if state == RUNNING
|
if state == RUNNING
|
||||||
&& let Err(new) = self.state.compare_exchange_weak(RUNNING, QUEUED, Relaxed, Acquire)
|
&& let Err(new) =
|
||||||
|
self.state.compare_exchange_weak(RUNNING, QUEUED, Relaxed, Acquire)
|
||||||
{
|
{
|
||||||
state = new;
|
state = new;
|
||||||
continue;
|
continue;
|
||||||
|
@ -164,8 +164,8 @@ impl Cfg {
|
|||||||
/// Renders the configuration for human display, as a short HTML description.
|
/// Renders the configuration for human display, as a short HTML description.
|
||||||
pub(crate) fn render_short_html(&self) -> String {
|
pub(crate) fn render_short_html(&self) -> String {
|
||||||
let mut msg = Display(self, Format::ShortHtml).to_string();
|
let mut msg = Display(self, Format::ShortHtml).to_string();
|
||||||
if self.should_capitalize_first_letter() &&
|
if self.should_capitalize_first_letter()
|
||||||
let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric())
|
&& let Some(i) = msg.find(|c: char| c.is_ascii_alphanumeric())
|
||||||
{
|
{
|
||||||
msg[i..i + 1].make_ascii_uppercase();
|
msg[i..i + 1].make_ascii_uppercase();
|
||||||
}
|
}
|
||||||
|
@ -374,15 +374,17 @@ pub(crate) fn build_impl(
|
|||||||
|
|
||||||
// Only inline impl if the implemented trait is
|
// Only inline impl if the implemented trait is
|
||||||
// reachable in rustdoc generated documentation
|
// reachable in rustdoc generated documentation
|
||||||
if !did.is_local() && let Some(traitref) = associated_trait {
|
if !did.is_local()
|
||||||
|
&& let Some(traitref) = associated_trait
|
||||||
|
{
|
||||||
let did = traitref.def_id;
|
let did = traitref.def_id;
|
||||||
if !cx.cache.effective_visibilities.is_directly_public(tcx, did) {
|
if !cx.cache.effective_visibilities.is_directly_public(tcx, did) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(stab) = tcx.lookup_stability(did) &&
|
if let Some(stab) = tcx.lookup_stability(did)
|
||||||
stab.is_unstable() &&
|
&& stab.is_unstable()
|
||||||
stab.feature == sym::rustc_private
|
&& stab.feature == sym::rustc_private
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -514,7 +516,10 @@ pub(crate) fn build_impl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
while let Some(ty) = stack.pop() {
|
while let Some(ty) = stack.pop() {
|
||||||
if let Some(did) = ty.def_id(&cx.cache) && !document_hidden && tcx.is_doc_hidden(did) {
|
if let Some(did) = ty.def_id(&cx.cache)
|
||||||
|
&& !document_hidden
|
||||||
|
&& tcx.is_doc_hidden(did)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if let Some(generics) = ty.generics() {
|
if let Some(generics) = ty.generics() {
|
||||||
@ -580,7 +585,8 @@ fn build_module_items(
|
|||||||
let res = item.res.expect_non_local();
|
let res = item.res.expect_non_local();
|
||||||
if let Some(def_id) = res.opt_def_id()
|
if let Some(def_id) = res.opt_def_id()
|
||||||
&& let Some(allowed_def_ids) = allowed_def_ids
|
&& let Some(allowed_def_ids) = allowed_def_ids
|
||||||
&& !allowed_def_ids.contains(&def_id) {
|
&& !allowed_def_ids.contains(&def_id)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if let Some(def_id) = res.mod_def_id() {
|
if let Some(def_id) = res.mod_def_id() {
|
||||||
|
@ -54,7 +54,9 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
|||||||
let mut inserted = FxHashSet::default();
|
let mut inserted = FxHashSet::default();
|
||||||
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
|
items.extend(doc.foreigns.iter().map(|(item, renamed)| {
|
||||||
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
|
let item = clean_maybe_renamed_foreign_item(cx, item, *renamed);
|
||||||
if let Some(name) = item.name && (cx.render_options.document_hidden || !item.is_doc_hidden()) {
|
if let Some(name) = item.name
|
||||||
|
&& (cx.render_options.document_hidden || !item.is_doc_hidden())
|
||||||
|
{
|
||||||
inserted.insert((item.type_(), name));
|
inserted.insert((item.type_(), name));
|
||||||
}
|
}
|
||||||
item
|
item
|
||||||
@ -85,7 +87,9 @@ pub(crate) fn clean_doc_module<'tcx>(doc: &DocModule<'tcx>, cx: &mut DocContext<
|
|||||||
}
|
}
|
||||||
let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id);
|
let v = clean_maybe_renamed_item(cx, item, *renamed, *import_id);
|
||||||
for item in &v {
|
for item in &v {
|
||||||
if let Some(name) = item.name && (cx.render_options.document_hidden || !item.is_doc_hidden()) {
|
if let Some(name) = item.name
|
||||||
|
&& (cx.render_options.document_hidden || !item.is_doc_hidden())
|
||||||
|
{
|
||||||
inserted.insert((item.type_(), name));
|
inserted.insert((item.type_(), name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -817,12 +821,7 @@ fn clean_ty_generics<'tcx>(
|
|||||||
{
|
{
|
||||||
let pred = clean_predicate(*pred, cx)?;
|
let pred = clean_predicate(*pred, cx)?;
|
||||||
|
|
||||||
bounds.extend(
|
bounds.extend(pred.get_bounds().into_iter().flatten().cloned());
|
||||||
pred.get_bounds()
|
|
||||||
.into_iter()
|
|
||||||
.flatten()
|
|
||||||
.cloned()
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(proj) = projection
|
if let Some(proj) = projection
|
||||||
&& let lhs = clean_projection(proj.map_bound(|p| p.projection_ty), cx, None)
|
&& let lhs = clean_projection(proj.map_bound(|p| p.projection_ty), cx, None)
|
||||||
@ -989,10 +988,8 @@ fn clean_proc_macro<'tcx>(
|
|||||||
cx: &mut DocContext<'tcx>,
|
cx: &mut DocContext<'tcx>,
|
||||||
) -> ItemKind {
|
) -> ItemKind {
|
||||||
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
let attrs = cx.tcx.hir().attrs(item.hir_id());
|
||||||
if kind == MacroKind::Derive &&
|
if kind == MacroKind::Derive
|
||||||
let Some(derive_name) = attrs
|
&& let Some(derive_name) = attrs.lists(sym::proc_macro_derive).find_map(|mi| mi.ident())
|
||||||
.lists(sym::proc_macro_derive)
|
|
||||||
.find_map(|mi| mi.ident())
|
|
||||||
{
|
{
|
||||||
*name = derive_name.name;
|
*name = derive_name.name;
|
||||||
}
|
}
|
||||||
@ -1154,7 +1151,9 @@ fn clean_fn_decl_with_args<'tcx>(
|
|||||||
hir::FnRetTy::Return(typ) => clean_ty(typ, cx),
|
hir::FnRetTy::Return(typ) => clean_ty(typ, cx),
|
||||||
hir::FnRetTy::DefaultReturn(..) => Type::Tuple(Vec::new()),
|
hir::FnRetTy::DefaultReturn(..) => Type::Tuple(Vec::new()),
|
||||||
};
|
};
|
||||||
if let Some(header) = header && header.is_async() {
|
if let Some(header) = header
|
||||||
|
&& header.is_async()
|
||||||
|
{
|
||||||
output = output.sugared_async_return_type();
|
output = output.sugared_async_return_type();
|
||||||
}
|
}
|
||||||
FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
|
FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
|
||||||
@ -1606,14 +1605,16 @@ fn first_non_private<'tcx>(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(def_id) = child.res.opt_def_id() && target_def_id == def_id {
|
if let Some(def_id) = child.res.opt_def_id()
|
||||||
|
&& target_def_id == def_id
|
||||||
|
{
|
||||||
let mut last_path_res = None;
|
let mut last_path_res = None;
|
||||||
'reexps: for reexp in child.reexport_chain.iter() {
|
'reexps: for reexp in child.reexport_chain.iter() {
|
||||||
if let Some(use_def_id) = reexp.id() &&
|
if let Some(use_def_id) = reexp.id()
|
||||||
let Some(local_use_def_id) = use_def_id.as_local() &&
|
&& let Some(local_use_def_id) = use_def_id.as_local()
|
||||||
let Some(hir::Node::Item(item)) = hir.find_by_def_id(local_use_def_id) &&
|
&& let Some(hir::Node::Item(item)) = hir.find_by_def_id(local_use_def_id)
|
||||||
!item.ident.name.is_empty() &&
|
&& !item.ident.name.is_empty()
|
||||||
let hir::ItemKind::Use(path, _) = item.kind
|
&& let hir::ItemKind::Use(path, _) = item.kind
|
||||||
{
|
{
|
||||||
for res in &path.res {
|
for res in &path.res {
|
||||||
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
|
if let Res::Def(DefKind::Ctor(..), _) | Res::SelfCtor(..) = res {
|
||||||
@ -1624,7 +1625,8 @@ fn first_non_private<'tcx>(
|
|||||||
// We never check for "cx.render_options.document_private"
|
// We never check for "cx.render_options.document_private"
|
||||||
// because if a re-export is not fully public, it's never
|
// because if a re-export is not fully public, it's never
|
||||||
// documented.
|
// documented.
|
||||||
cx.tcx.local_visibility(local_use_def_id).is_public() {
|
cx.tcx.local_visibility(local_use_def_id).is_public()
|
||||||
|
{
|
||||||
break 'reexps;
|
break 'reexps;
|
||||||
}
|
}
|
||||||
last_path_res = Some((path, res));
|
last_path_res = Some((path, res));
|
||||||
@ -1639,7 +1641,12 @@ fn first_non_private<'tcx>(
|
|||||||
// 1. We found a public reexport.
|
// 1. We found a public reexport.
|
||||||
// 2. We didn't find a public reexport so it's the "end type" path.
|
// 2. We didn't find a public reexport so it's the "end type" path.
|
||||||
if let Some((new_path, _)) = last_path_res {
|
if let Some((new_path, _)) = last_path_res {
|
||||||
return Some(first_non_private_clean_path(cx, path, new_path.segments, new_path.span));
|
return Some(first_non_private_clean_path(
|
||||||
|
cx,
|
||||||
|
path,
|
||||||
|
new_path.segments,
|
||||||
|
new_path.span,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
// If `last_path_res` is `None`, it can mean two things:
|
// If `last_path_res` is `None`, it can mean two things:
|
||||||
//
|
//
|
||||||
@ -2304,7 +2311,9 @@ fn clean_middle_opaque_bounds<'tcx>(
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(sized) = cx.tcx.lang_items().sized_trait() && trait_ref.def_id() == sized {
|
if let Some(sized) = cx.tcx.lang_items().sized_trait()
|
||||||
|
&& trait_ref.def_id() == sized
|
||||||
|
{
|
||||||
has_sized = true;
|
has_sized = true;
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
@ -2680,28 +2689,27 @@ fn add_without_unwanted_attributes<'hir>(
|
|||||||
let mut attr = attr.clone();
|
let mut attr = attr.clone();
|
||||||
match attr.kind {
|
match attr.kind {
|
||||||
ast::AttrKind::Normal(ref mut normal) => {
|
ast::AttrKind::Normal(ref mut normal) => {
|
||||||
if let [ident] = &*normal.item.path.segments &&
|
if let [ident] = &*normal.item.path.segments
|
||||||
let ident = ident.ident.name &&
|
&& let ident = ident.ident.name
|
||||||
ident == sym::doc
|
&& ident == sym::doc
|
||||||
{
|
{
|
||||||
match normal.item.args {
|
match normal.item.args {
|
||||||
ast::AttrArgs::Delimited(ref mut args) => {
|
ast::AttrArgs::Delimited(ref mut args) => {
|
||||||
let tokens =
|
let tokens = filter_tokens_from_list(&args.tokens, |token| {
|
||||||
filter_tokens_from_list(&args.tokens, |token| {
|
!matches!(
|
||||||
!matches!(
|
token,
|
||||||
token,
|
TokenTree::Token(
|
||||||
TokenTree::Token(
|
Token {
|
||||||
Token {
|
kind: TokenKind::Ident(
|
||||||
kind: TokenKind::Ident(
|
sym::hidden | sym::inline | sym::no_inline,
|
||||||
sym::hidden | sym::inline | sym::no_inline,
|
_,
|
||||||
_,
|
),
|
||||||
),
|
..
|
||||||
..
|
},
|
||||||
},
|
_,
|
||||||
_,
|
),
|
||||||
),
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
args.tokens = TokenStream::new(tokens);
|
args.tokens = TokenStream::new(tokens);
|
||||||
attrs.push((Cow::Owned(attr), import_parent));
|
attrs.push((Cow::Owned(attr), import_parent));
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,8 @@ pub(crate) fn move_bounds_to_generic_parameters(generics: &mut clean::Generics)
|
|||||||
}) = generics.params.iter_mut().find(|param| ¶m.name == arg)
|
}) = generics.params.iter_mut().find(|param| ¶m.name == arg)
|
||||||
{
|
{
|
||||||
param_bounds.extend(bounds.drain(..));
|
param_bounds.extend(bounds.drain(..));
|
||||||
} else if let WherePredicate::RegionPredicate { lifetime: Lifetime(arg), bounds } = &mut pred
|
} else if let WherePredicate::RegionPredicate { lifetime: Lifetime(arg), bounds } =
|
||||||
|
&mut pred
|
||||||
&& let Some(GenericParamDef {
|
&& let Some(GenericParamDef {
|
||||||
kind: GenericParamDefKind::Lifetime { outlives: param_bounds },
|
kind: GenericParamDefKind::Lifetime { outlives: param_bounds },
|
||||||
..
|
..
|
||||||
|
@ -1269,8 +1269,8 @@ impl GenericBound {
|
|||||||
|
|
||||||
pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
|
pub(crate) fn is_sized_bound(&self, cx: &DocContext<'_>) -> bool {
|
||||||
use rustc_hir::TraitBoundModifier as TBM;
|
use rustc_hir::TraitBoundModifier as TBM;
|
||||||
if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self &&
|
if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self
|
||||||
Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait()
|
&& Some(trait_.def_id()) == cx.tcx.lang_items().sized_trait()
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1623,7 +1623,7 @@ impl Type {
|
|||||||
/// functions.
|
/// functions.
|
||||||
pub(crate) fn sugared_async_return_type(self) -> Type {
|
pub(crate) fn sugared_async_return_type(self) -> Type {
|
||||||
if let Type::ImplTrait(mut v) = self
|
if let Type::ImplTrait(mut v) = self
|
||||||
&& let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _ )) = v.pop()
|
&& let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _)) = v.pop()
|
||||||
&& let Some(segment) = trait_.segments.pop()
|
&& let Some(segment) = trait_.segments.pop()
|
||||||
&& let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args
|
&& let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args
|
||||||
&& let Some(binding) = bindings.pop()
|
&& let Some(binding) = bindings.pop()
|
||||||
|
@ -443,8 +443,8 @@ pub(crate) fn is_literal_expr(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let hir::ExprKind::Unary(hir::UnOp::Neg, expr) = &expr.kind &&
|
if let hir::ExprKind::Unary(hir::UnOp::Neg, expr) = &expr.kind
|
||||||
let hir::ExprKind::Lit(_) = &expr.kind
|
&& let hir::ExprKind::Lit(_) = &expr.kind
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -643,17 +643,16 @@ pub(crate) fn inherits_doc_hidden(
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
let hir = tcx.hir();
|
let hir = tcx.hir();
|
||||||
while let Some(id) = tcx.opt_local_parent(def_id) {
|
while let Some(id) = tcx.opt_local_parent(def_id) {
|
||||||
if let Some(stop_at) = stop_at && id == stop_at {
|
if let Some(stop_at) = stop_at
|
||||||
|
&& id == stop_at
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
def_id = id;
|
def_id = id;
|
||||||
if tcx.is_doc_hidden(def_id.to_def_id()) {
|
if tcx.is_doc_hidden(def_id.to_def_id()) {
|
||||||
return true;
|
return true;
|
||||||
} else if let Some(node) = hir.find_by_def_id(def_id) &&
|
} else if let Some(node) = hir.find_by_def_id(def_id)
|
||||||
matches!(
|
&& matches!(node, hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }),)
|
||||||
node,
|
|
||||||
hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(_), .. }),
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
// `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly
|
// `impl` blocks stand a bit on their own: unless they have `#[doc(hidden)]` directly
|
||||||
// on them, they don't inherit it from the parent context.
|
// on them, they don't inherit it from the parent context.
|
||||||
|
@ -597,15 +597,15 @@ pub(crate) fn make_test(
|
|||||||
loop {
|
loop {
|
||||||
match parser.parse_item(ForceCollect::No) {
|
match parser.parse_item(ForceCollect::No) {
|
||||||
Ok(Some(item)) => {
|
Ok(Some(item)) => {
|
||||||
if !found_main &&
|
if !found_main
|
||||||
let ast::ItemKind::Fn(..) = item.kind &&
|
&& let ast::ItemKind::Fn(..) = item.kind
|
||||||
item.ident.name == sym::main
|
&& item.ident.name == sym::main
|
||||||
{
|
{
|
||||||
found_main = true;
|
found_main = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !found_extern_crate &&
|
if !found_extern_crate
|
||||||
let ast::ItemKind::ExternCrate(original) = item.kind
|
&& let ast::ItemKind::ExternCrate(original) = item.kind
|
||||||
{
|
{
|
||||||
// This code will never be reached if `crate_name` is none because
|
// This code will never be reached if `crate_name` is none because
|
||||||
// `found_extern_crate` is initialized to `true` if it is none.
|
// `found_extern_crate` is initialized to `true` if it is none.
|
||||||
@ -957,10 +957,10 @@ impl Collector {
|
|||||||
fn get_filename(&self) -> FileName {
|
fn get_filename(&self) -> FileName {
|
||||||
if let Some(ref source_map) = self.source_map {
|
if let Some(ref source_map) = self.source_map {
|
||||||
let filename = source_map.span_to_filename(self.position);
|
let filename = source_map.span_to_filename(self.position);
|
||||||
if let FileName::Real(ref filename) = filename &&
|
if let FileName::Real(ref filename) = filename
|
||||||
let Ok(cur_dir) = env::current_dir() &&
|
&& let Ok(cur_dir) = env::current_dir()
|
||||||
let Some(local_path) = filename.local_path() &&
|
&& let Some(local_path) = filename.local_path()
|
||||||
let Ok(path) = local_path.strip_prefix(&cur_dir)
|
&& let Ok(path) = local_path.strip_prefix(&cur_dir)
|
||||||
{
|
{
|
||||||
return path.to_owned().into();
|
return path.to_owned().into();
|
||||||
}
|
}
|
||||||
|
@ -230,8 +230,8 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||||||
|
|
||||||
// If the impl is from a masked crate or references something from a
|
// If the impl is from a masked crate or references something from a
|
||||||
// masked crate then remove it completely.
|
// masked crate then remove it completely.
|
||||||
if let clean::ImplItem(ref i) = *item.kind &&
|
if let clean::ImplItem(ref i) = *item.kind
|
||||||
(self.cache.masked_crates.contains(&item.item_id.krate())
|
&& (self.cache.masked_crates.contains(&item.item_id.krate())
|
||||||
|| i.trait_
|
|| i.trait_
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map_or(false, |t| is_from_private_dep(self.tcx, self.cache, t.def_id()))
|
.map_or(false, |t| is_from_private_dep(self.tcx, self.cache, t.def_id()))
|
||||||
@ -249,9 +249,9 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Collect all the implementors of traits.
|
// Collect all the implementors of traits.
|
||||||
if let clean::ImplItem(ref i) = *item.kind &&
|
if let clean::ImplItem(ref i) = *item.kind
|
||||||
let Some(trait_) = &i.trait_ &&
|
&& let Some(trait_) = &i.trait_
|
||||||
!i.kind.is_blanket()
|
&& !i.kind.is_blanket()
|
||||||
{
|
{
|
||||||
self.cache
|
self.cache
|
||||||
.implementors
|
.implementors
|
||||||
@ -264,8 +264,9 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||||||
if let Some(s) = item.name.or_else(|| {
|
if let Some(s) = item.name.or_else(|| {
|
||||||
if item.is_stripped() {
|
if item.is_stripped() {
|
||||||
None
|
None
|
||||||
} else if let clean::ImportItem(ref i) = *item.kind &&
|
} else if let clean::ImportItem(ref i) = *item.kind
|
||||||
let clean::ImportKind::Simple(s) = i.kind {
|
&& let clean::ImportKind::Simple(s) = i.kind
|
||||||
|
{
|
||||||
Some(s)
|
Some(s)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -357,7 +358,9 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||||||
desc,
|
desc,
|
||||||
parent,
|
parent,
|
||||||
parent_idx: None,
|
parent_idx: None,
|
||||||
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) = self.cache.parent_stack.last() {
|
impl_id: if let Some(ParentStackItem::Impl { item_id, .. }) =
|
||||||
|
self.cache.parent_stack.last()
|
||||||
|
{
|
||||||
item_id.as_def_id()
|
item_id.as_def_id()
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -493,9 +496,11 @@ impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
|
|||||||
clean::Type::Path { ref path }
|
clean::Type::Path { ref path }
|
||||||
| clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. } => {
|
| clean::BorrowedRef { type_: box clean::Type::Path { ref path }, .. } => {
|
||||||
dids.insert(path.def_id());
|
dids.insert(path.def_id());
|
||||||
if let Some(generics) = path.generics() &&
|
if let Some(generics) = path.generics()
|
||||||
let ty::Adt(adt, _) = self.tcx.type_of(path.def_id()).instantiate_identity().kind() &&
|
&& let ty::Adt(adt, _) =
|
||||||
adt.is_fundamental() {
|
self.tcx.type_of(path.def_id()).instantiate_identity().kind()
|
||||||
|
&& adt.is_fundamental()
|
||||||
|
{
|
||||||
for ty in generics {
|
for ty in generics {
|
||||||
if let Some(did) = ty.def_id(self.cache) {
|
if let Some(did) = ty.def_id(self.cache) {
|
||||||
dids.insert(did);
|
dids.insert(did);
|
||||||
|
@ -1166,13 +1166,17 @@ fn fmt_type<'cx>(
|
|||||||
// we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
|
// we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).
|
||||||
|
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
if let Some(trait_) = trait_ && should_show_cast {
|
if let Some(trait_) = trait_
|
||||||
|
&& should_show_cast
|
||||||
|
{
|
||||||
write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
|
write!(f, "<{:#} as {:#}>::", self_type.print(cx), trait_.print(cx))?
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{:#}::", self_type.print(cx))?
|
write!(f, "{:#}::", self_type.print(cx))?
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if let Some(trait_) = trait_ && should_show_cast {
|
if let Some(trait_) = trait_
|
||||||
|
&& should_show_cast
|
||||||
|
{
|
||||||
write!(f, "<{} as {}>::", self_type.print(cx), trait_.print(cx))?
|
write!(f, "<{} as {}>::", self_type.print(cx), trait_.print(cx))?
|
||||||
} else {
|
} else {
|
||||||
write!(f, "{}::", self_type.print(cx))?
|
write!(f, "{}::", self_type.print(cx))?
|
||||||
@ -1268,16 +1272,23 @@ impl clean::Impl {
|
|||||||
write!(f, " for ")?;
|
write!(f, " for ")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let clean::Type::Tuple(types) = &self.for_ &&
|
if let clean::Type::Tuple(types) = &self.for_
|
||||||
let [clean::Type::Generic(name)] = &types[..] &&
|
&& let [clean::Type::Generic(name)] = &types[..]
|
||||||
(self.kind.is_fake_variadic() || self.kind.is_auto())
|
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
|
||||||
{
|
{
|
||||||
// Hardcoded anchor library/core/src/primitive_docs.rs
|
// Hardcoded anchor library/core/src/primitive_docs.rs
|
||||||
// Link should match `# Trait implementations`
|
// Link should match `# Trait implementations`
|
||||||
primitive_link_fragment(f, PrimitiveType::Tuple, format_args!("({name}₁, {name}₂, …, {name}ₙ)"), "#trait-implementations-1", cx)?;
|
primitive_link_fragment(
|
||||||
} else if let clean::BareFunction(bare_fn) = &self.for_ &&
|
f,
|
||||||
let [clean::Argument { type_: clean::Type::Generic(name), .. }] = &bare_fn.decl.inputs.values[..] &&
|
PrimitiveType::Tuple,
|
||||||
(self.kind.is_fake_variadic() || self.kind.is_auto())
|
format_args!("({name}₁, {name}₂, …, {name}ₙ)"),
|
||||||
|
"#trait-implementations-1",
|
||||||
|
cx,
|
||||||
|
)?;
|
||||||
|
} else if let clean::BareFunction(bare_fn) = &self.for_
|
||||||
|
&& let [clean::Argument { type_: clean::Type::Generic(name), .. }] =
|
||||||
|
&bare_fn.decl.inputs.values[..]
|
||||||
|
&& (self.kind.is_fake_variadic() || self.kind.is_auto())
|
||||||
{
|
{
|
||||||
// Hardcoded anchor library/core/src/primitive_docs.rs
|
// Hardcoded anchor library/core/src/primitive_docs.rs
|
||||||
// Link should match `# Trait implementations`
|
// Link should match `# Trait implementations`
|
||||||
@ -1286,22 +1297,18 @@ impl clean::Impl {
|
|||||||
let unsafety = bare_fn.unsafety.print_with_space();
|
let unsafety = bare_fn.unsafety.print_with_space();
|
||||||
let abi = print_abi_with_space(bare_fn.abi);
|
let abi = print_abi_with_space(bare_fn.abi);
|
||||||
if f.alternate() {
|
if f.alternate() {
|
||||||
write!(
|
write!(f, "{hrtb:#}{unsafety}{abi:#}",)?;
|
||||||
f,
|
|
||||||
"{hrtb:#}{unsafety}{abi:#}",
|
|
||||||
)?;
|
|
||||||
} else {
|
} else {
|
||||||
write!(
|
write!(f, "{hrtb}{unsafety}{abi}",)?;
|
||||||
f,
|
|
||||||
"{hrtb}{unsafety}{abi}",
|
|
||||||
)?;
|
|
||||||
}
|
}
|
||||||
let ellipsis = if bare_fn.decl.c_variadic {
|
let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };
|
||||||
", ..."
|
primitive_link_fragment(
|
||||||
} else {
|
f,
|
||||||
""
|
PrimitiveType::Tuple,
|
||||||
};
|
format_args!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"),
|
||||||
primitive_link_fragment(f, PrimitiveType::Tuple, format_args!("fn ({name}₁, {name}₂, …, {name}ₙ{ellipsis})"), "#trait-implementations-1", cx)?;
|
"#trait-implementations-1",
|
||||||
|
cx,
|
||||||
|
)?;
|
||||||
// Write output.
|
// Write output.
|
||||||
if !bare_fn.decl.output.is_unit() {
|
if !bare_fn.decl.output.is_unit() {
|
||||||
write!(f, " -> ")?;
|
write!(f, " -> ")?;
|
||||||
@ -1447,7 +1454,9 @@ impl clean::FnDecl {
|
|||||||
let amp = if f.alternate() { "&" } else { "&" };
|
let amp = if f.alternate() { "&" } else { "&" };
|
||||||
|
|
||||||
write!(f, "(")?;
|
write!(f, "(")?;
|
||||||
if let Some(n) = line_wrapping_indent && !self.inputs.values.is_empty() {
|
if let Some(n) = line_wrapping_indent
|
||||||
|
&& !self.inputs.values.is_empty()
|
||||||
|
{
|
||||||
write!(f, "\n{}", Indent(n + 4))?;
|
write!(f, "\n{}", Indent(n + 4))?;
|
||||||
}
|
}
|
||||||
for (i, input) in self.inputs.values.iter().enumerate() {
|
for (i, input) in self.inputs.values.iter().enumerate() {
|
||||||
|
@ -185,8 +185,8 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> {
|
|||||||
if self.pending_elems.is_empty() {
|
if self.pending_elems.is_empty() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if let Some((_, parent_class)) = self.closing_tags.last() &&
|
if let Some((_, parent_class)) = self.closing_tags.last()
|
||||||
can_merge(current_class, Some(*parent_class), "")
|
&& can_merge(current_class, Some(*parent_class), "")
|
||||||
{
|
{
|
||||||
for (text, class) in self.pending_elems.iter() {
|
for (text, class) in self.pending_elems.iter() {
|
||||||
string(self.out, Escape(text), *class, &self.href_context, false);
|
string(self.out, Escape(text), *class, &self.href_context, false);
|
||||||
@ -194,7 +194,9 @@ impl<'a, 'tcx, F: Write> TokenHandler<'a, 'tcx, F> {
|
|||||||
} else {
|
} else {
|
||||||
// We only want to "open" the tag ourselves if we have more than one pending and if the
|
// We only want to "open" the tag ourselves if we have more than one pending and if the
|
||||||
// current parent tag is not the same as our pending content.
|
// current parent tag is not the same as our pending content.
|
||||||
let close_tag = if self.pending_elems.len() > 1 && let Some(current_class) = current_class {
|
let close_tag = if self.pending_elems.len() > 1
|
||||||
|
&& let Some(current_class) = current_class
|
||||||
|
{
|
||||||
Some(enter_span(self.out, current_class, &self.href_context))
|
Some(enter_span(self.out, current_class, &self.href_context))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -260,10 +262,12 @@ pub(super) fn write_code(
|
|||||||
Highlight::Token { text, class } => {
|
Highlight::Token { text, class } => {
|
||||||
// If we received a `ExitSpan` event and then have a non-compatible `Class`, we
|
// If we received a `ExitSpan` event and then have a non-compatible `Class`, we
|
||||||
// need to close the `<span>`.
|
// need to close the `<span>`.
|
||||||
let need_current_class_update = if let Some(pending) = token_handler.pending_exit_span &&
|
let need_current_class_update = if let Some(pending) =
|
||||||
!can_merge(Some(pending), class, text) {
|
token_handler.pending_exit_span
|
||||||
token_handler.handle_exit_span();
|
&& !can_merge(Some(pending), class, text)
|
||||||
true
|
{
|
||||||
|
token_handler.handle_exit_span();
|
||||||
|
true
|
||||||
// If the two `Class` are different, time to flush the current content and start
|
// If the two `Class` are different, time to flush the current content and start
|
||||||
// a new one.
|
// a new one.
|
||||||
} else if !can_merge(token_handler.current_class, class, text) {
|
} else if !can_merge(token_handler.current_class, class, text) {
|
||||||
@ -293,7 +297,8 @@ pub(super) fn write_code(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if should_add {
|
if should_add {
|
||||||
let closing_tag = enter_span(token_handler.out, class, &token_handler.href_context);
|
let closing_tag =
|
||||||
|
enter_span(token_handler.out, class, &token_handler.href_context);
|
||||||
token_handler.closing_tags.push((closing_tag, class));
|
token_handler.closing_tags.push((closing_tag, class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,8 +307,14 @@ pub(super) fn write_code(
|
|||||||
}
|
}
|
||||||
Highlight::ExitSpan => {
|
Highlight::ExitSpan => {
|
||||||
token_handler.current_class = None;
|
token_handler.current_class = None;
|
||||||
token_handler.pending_exit_span =
|
token_handler.pending_exit_span = Some(
|
||||||
Some(token_handler.closing_tags.last().as_ref().expect("ExitSpan without EnterSpan").1);
|
token_handler
|
||||||
|
.closing_tags
|
||||||
|
.last()
|
||||||
|
.as_ref()
|
||||||
|
.expect("ExitSpan without EnterSpan")
|
||||||
|
.1,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -466,7 +477,9 @@ impl<'a> PeekIter<'a> {
|
|||||||
}
|
}
|
||||||
/// Returns the next item after the current one. It doesn't interfere with `peek_next` output.
|
/// Returns the next item after the current one. It doesn't interfere with `peek_next` output.
|
||||||
fn peek(&mut self) -> Option<&(TokenKind, &'a str)> {
|
fn peek(&mut self) -> Option<&(TokenKind, &'a str)> {
|
||||||
if self.stored.is_empty() && let Some(next) = self.iter.next() {
|
if self.stored.is_empty()
|
||||||
|
&& let Some(next) = self.iter.next()
|
||||||
|
{
|
||||||
self.stored.push_back(next);
|
self.stored.push_back(next);
|
||||||
}
|
}
|
||||||
self.stored.front()
|
self.stored.front()
|
||||||
|
@ -1119,10 +1119,10 @@ impl<'a, 'tcx> TagIterator<'a, 'tcx> {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let indices = self.parse_string(pos)?;
|
let indices = self.parse_string(pos)?;
|
||||||
if let Some((_, c)) = self.inner.peek().copied() &&
|
if let Some((_, c)) = self.inner.peek().copied()
|
||||||
c != '{' &&
|
&& c != '{'
|
||||||
!is_separator(c) &&
|
&& !is_separator(c)
|
||||||
c != '('
|
&& c != '('
|
||||||
{
|
{
|
||||||
self.emit_error(format!("expected ` `, `{{` or `,` after `\"`, found `{c}`"));
|
self.emit_error(format!("expected ` `, `{{` or `,` after `\"`, found `{c}`"));
|
||||||
return None;
|
return None;
|
||||||
|
@ -176,9 +176,9 @@ impl<'tcx> Context<'tcx> {
|
|||||||
let mut render_redirect_pages = self.render_redirect_pages;
|
let mut render_redirect_pages = self.render_redirect_pages;
|
||||||
// If the item is stripped but inlined, links won't point to the item so no need to generate
|
// If the item is stripped but inlined, links won't point to the item so no need to generate
|
||||||
// a file for it.
|
// a file for it.
|
||||||
if it.is_stripped() &&
|
if it.is_stripped()
|
||||||
let Some(def_id) = it.def_id() &&
|
&& let Some(def_id) = it.def_id()
|
||||||
def_id.is_local()
|
&& def_id.is_local()
|
||||||
{
|
{
|
||||||
if self.is_inside_inlined_module || self.shared.cache.inlined_items.contains(&def_id) {
|
if self.is_inside_inlined_module || self.shared.cache.inlined_items.contains(&def_id) {
|
||||||
// For now we're forced to generate a redirect page for stripped items until
|
// For now we're forced to generate a redirect page for stripped items until
|
||||||
@ -371,7 +371,9 @@ impl<'tcx> Context<'tcx> {
|
|||||||
|
|
||||||
path = href.into_inner().to_string_lossy().into_owned();
|
path = href.into_inner().to_string_lossy().into_owned();
|
||||||
|
|
||||||
if let Some(c) = path.as_bytes().last() && *c != b'/' {
|
if let Some(c) = path.as_bytes().last()
|
||||||
|
&& *c != b'/'
|
||||||
|
{
|
||||||
path.push('/');
|
path.push('/');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,9 +743,10 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||||||
shared.fs.write(scrape_examples_help_file, v)?;
|
shared.fs.write(scrape_examples_help_file, v)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(ref redirections) = shared.redirections && !redirections.borrow().is_empty() {
|
if let Some(ref redirections) = shared.redirections
|
||||||
let redirect_map_path =
|
&& !redirections.borrow().is_empty()
|
||||||
self.dst.join(crate_name.as_str()).join("redirect-map.json");
|
{
|
||||||
|
let redirect_map_path = self.dst.join(crate_name.as_str()).join("redirect-map.json");
|
||||||
let paths = serde_json::to_string(&*redirections.borrow()).unwrap();
|
let paths = serde_json::to_string(&*redirections.borrow()).unwrap();
|
||||||
shared.ensure_dir(&self.dst.join(crate_name.as_str()))?;
|
shared.ensure_dir(&self.dst.join(crate_name.as_str()))?;
|
||||||
shared.fs.write(redirect_map_path, paths)?;
|
shared.fs.write(redirect_map_path, paths)?;
|
||||||
@ -790,7 +793,9 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !self.is_inside_inlined_module {
|
if !self.is_inside_inlined_module {
|
||||||
if let Some(def_id) = item.def_id() && self.cache().inlined_items.contains(&def_id) {
|
if let Some(def_id) = item.def_id()
|
||||||
|
&& self.cache().inlined_items.contains(&def_id)
|
||||||
|
{
|
||||||
self.is_inside_inlined_module = true;
|
self.is_inside_inlined_module = true;
|
||||||
}
|
}
|
||||||
} else if !self.cache().document_hidden && item.is_doc_hidden() {
|
} else if !self.cache().document_hidden && item.is_doc_hidden() {
|
||||||
|
@ -180,7 +180,9 @@ impl Serialize for IndexItemFunctionType {
|
|||||||
_ => seq.serialize_element(&self.output)?,
|
_ => seq.serialize_element(&self.output)?,
|
||||||
}
|
}
|
||||||
for constraint in &self.where_clause {
|
for constraint in &self.where_clause {
|
||||||
if let [one] = &constraint[..] && one.generics.is_none() {
|
if let [one] = &constraint[..]
|
||||||
|
&& one.generics.is_none()
|
||||||
|
{
|
||||||
seq.serialize_element(one)?;
|
seq.serialize_element(one)?;
|
||||||
} else {
|
} else {
|
||||||
seq.serialize_element(constraint)?;
|
seq.serialize_element(constraint)?;
|
||||||
@ -915,7 +917,9 @@ fn render_stability_since_raw_with_extra(
|
|||||||
containing_const_ver: Option<StableSince>,
|
containing_const_ver: Option<StableSince>,
|
||||||
extra_class: &str,
|
extra_class: &str,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let stable_version = if ver != containing_ver && let Some(ver) = &ver {
|
let stable_version = if ver != containing_ver
|
||||||
|
&& let Some(ver) = &ver
|
||||||
|
{
|
||||||
since_to_string(ver)
|
since_to_string(ver)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -974,8 +974,9 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
|
|||||||
// if any Types with the same name but different DefId have been found.
|
// if any Types with the same name but different DefId have been found.
|
||||||
let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
|
let mut implementor_dups: FxHashMap<Symbol, (DefId, bool)> = FxHashMap::default();
|
||||||
for implementor in implementors {
|
for implementor in implementors {
|
||||||
if let Some(did) = implementor.inner_impl().for_.without_borrowed_ref().def_id(cache) &&
|
if let Some(did) = implementor.inner_impl().for_.without_borrowed_ref().def_id(cache)
|
||||||
!did.is_local() {
|
&& !did.is_local()
|
||||||
|
{
|
||||||
extern_crates.insert(did.krate);
|
extern_crates.insert(did.krate);
|
||||||
}
|
}
|
||||||
match implementor.inner_impl().for_.without_borrowed_ref() {
|
match implementor.inner_impl().for_.without_borrowed_ref() {
|
||||||
@ -1152,9 +1153,10 @@ fn item_trait(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean:
|
|||||||
.take(cx.current.len())
|
.take(cx.current.len())
|
||||||
.chain(std::iter::once("trait.impl"))
|
.chain(std::iter::once("trait.impl"))
|
||||||
.collect();
|
.collect();
|
||||||
if let Some(did) = it.item_id.as_def_id() &&
|
if let Some(did) = it.item_id.as_def_id()
|
||||||
let get_extern = { || cache.external_paths.get(&did).map(|s| &s.0) } &&
|
&& let get_extern = { || cache.external_paths.get(&did).map(|s| &s.0) }
|
||||||
let Some(fqp) = cache.exact_paths.get(&did).or_else(get_extern) {
|
&& let Some(fqp) = cache.exact_paths.get(&did).or_else(get_extern)
|
||||||
|
{
|
||||||
js_src_path.extend(fqp[..fqp.len() - 1].iter().copied());
|
js_src_path.extend(fqp[..fqp.len() - 1].iter().copied());
|
||||||
js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap()));
|
js_src_path.push_fmt(format_args!("{}.{}.js", it.type_(), fqp.last().unwrap()));
|
||||||
} else {
|
} else {
|
||||||
@ -1564,8 +1566,8 @@ fn should_show_enum_discriminant(
|
|||||||
) -> bool {
|
) -> bool {
|
||||||
let mut has_variants_with_value = false;
|
let mut has_variants_with_value = false;
|
||||||
for variant in variants {
|
for variant in variants {
|
||||||
if let clean::VariantItem(ref var) = *variant.kind &&
|
if let clean::VariantItem(ref var) = *variant.kind
|
||||||
matches!(var.kind, clean::VariantKind::CLike)
|
&& matches!(var.kind, clean::VariantKind::CLike)
|
||||||
{
|
{
|
||||||
has_variants_with_value |= var.discriminant.is_some();
|
has_variants_with_value |= var.discriminant.is_some();
|
||||||
} else {
|
} else {
|
||||||
@ -1706,8 +1708,8 @@ fn item_variants(
|
|||||||
" rightside",
|
" rightside",
|
||||||
);
|
);
|
||||||
w.write_str("<h3 class=\"code-header\">");
|
w.write_str("<h3 class=\"code-header\">");
|
||||||
if let clean::VariantItem(ref var) = *variant.kind &&
|
if let clean::VariantItem(ref var) = *variant.kind
|
||||||
let clean::VariantKind::CLike = var.kind
|
&& let clean::VariantKind::CLike = var.kind
|
||||||
{
|
{
|
||||||
display_c_like_variant(
|
display_c_like_variant(
|
||||||
w,
|
w,
|
||||||
|
@ -228,10 +228,11 @@ pub(crate) fn build_index<'tcx>(
|
|||||||
let mut associated_item_duplicates = FxHashMap::<(isize, ItemType, Symbol), usize>::default();
|
let mut associated_item_duplicates = FxHashMap::<(isize, ItemType, Symbol), usize>::default();
|
||||||
|
|
||||||
for &item in &crate_items {
|
for &item in &crate_items {
|
||||||
if item.impl_id.is_some() && let Some(parent_idx) = item.parent_idx {
|
if item.impl_id.is_some()
|
||||||
let count = associated_item_duplicates
|
&& let Some(parent_idx) = item.parent_idx
|
||||||
.entry((parent_idx, item.ty, item.name))
|
{
|
||||||
.or_insert(0);
|
let count =
|
||||||
|
associated_item_duplicates.entry((parent_idx, item.ty, item.name)).or_insert(0);
|
||||||
*count += 1;
|
*count += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -435,9 +435,9 @@ fn sidebar_deref_methods<'a>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Recurse into any further impls that might exist for `target`
|
// Recurse into any further impls that might exist for `target`
|
||||||
if let Some(target_did) = target.def_id(c) &&
|
if let Some(target_did) = target.def_id(c)
|
||||||
let Some(target_impls) = c.impls.get(&target_did) &&
|
&& let Some(target_impls) = c.impls.get(&target_did)
|
||||||
let Some(target_deref_impl) = target_impls.iter().find(|i| {
|
&& let Some(target_deref_impl) = target_impls.iter().find(|i| {
|
||||||
i.inner_impl()
|
i.inner_impl()
|
||||||
.trait_
|
.trait_
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -445,14 +445,7 @@ fn sidebar_deref_methods<'a>(
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
{
|
{
|
||||||
sidebar_deref_methods(
|
sidebar_deref_methods(cx, out, target_deref_impl, target_impls, derefs, used_links);
|
||||||
cx,
|
|
||||||
out,
|
|
||||||
target_deref_impl,
|
|
||||||
target_impls,
|
|
||||||
derefs,
|
|
||||||
used_links,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -494,8 +487,13 @@ fn sidebar_module(items: &[clean::Item]) -> LinkBlock<'static> {
|
|||||||
&& it
|
&& it
|
||||||
.name
|
.name
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
if let clean::ImportItem(ref i) = *it.kind &&
|
if let clean::ImportItem(ref i) = *it.kind
|
||||||
let clean::ImportKind::Simple(s) = i.kind { Some(s) } else { None }
|
&& let clean::ImportKind::Simple(s) = i.kind
|
||||||
|
{
|
||||||
|
Some(s)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.is_some()
|
.is_some()
|
||||||
})
|
})
|
||||||
|
@ -42,37 +42,35 @@ pub(crate) fn document_type_layout<'a, 'cx: 'a>(
|
|||||||
let ty = tcx.type_of(ty_def_id).instantiate_identity();
|
let ty = tcx.type_of(ty_def_id).instantiate_identity();
|
||||||
let type_layout = tcx.layout_of(param_env.and(ty));
|
let type_layout = tcx.layout_of(param_env.and(ty));
|
||||||
|
|
||||||
let variants =
|
let variants = if let Ok(type_layout) = type_layout
|
||||||
if let Ok(type_layout) = type_layout &&
|
&& let Variants::Multiple { variants, tag, tag_encoding, .. } =
|
||||||
let Variants::Multiple { variants, tag, tag_encoding, .. } =
|
type_layout.layout.variants()
|
||||||
type_layout.layout.variants() &&
|
&& !variants.is_empty()
|
||||||
!variants.is_empty()
|
{
|
||||||
{
|
let tag_size = if let TagEncoding::Niche { .. } = tag_encoding {
|
||||||
let tag_size =
|
0
|
||||||
if let TagEncoding::Niche { .. } = tag_encoding {
|
} else if let Primitive::Int(i, _) = tag.primitive() {
|
||||||
0
|
i.size().bytes()
|
||||||
} else if let Primitive::Int(i, _) = tag.primitive() {
|
|
||||||
i.size().bytes()
|
|
||||||
} else {
|
|
||||||
span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int")
|
|
||||||
};
|
|
||||||
variants
|
|
||||||
.iter_enumerated()
|
|
||||||
.map(|(variant_idx, variant_layout)| {
|
|
||||||
let Adt(adt, _) = type_layout.ty.kind() else {
|
|
||||||
span_bug!(tcx.def_span(ty_def_id), "not an adt")
|
|
||||||
};
|
|
||||||
let name = adt.variant(variant_idx).name;
|
|
||||||
let is_unsized = variant_layout.abi.is_unsized();
|
|
||||||
let is_uninhabited = variant_layout.abi.is_uninhabited();
|
|
||||||
let size = variant_layout.size.bytes() - tag_size;
|
|
||||||
let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size };
|
|
||||||
(name, type_layout_size)
|
|
||||||
})
|
|
||||||
.collect()
|
|
||||||
} else {
|
} else {
|
||||||
Vec::new()
|
span_bug!(tcx.def_span(ty_def_id), "tag is neither niche nor int")
|
||||||
};
|
};
|
||||||
|
variants
|
||||||
|
.iter_enumerated()
|
||||||
|
.map(|(variant_idx, variant_layout)| {
|
||||||
|
let Adt(adt, _) = type_layout.ty.kind() else {
|
||||||
|
span_bug!(tcx.def_span(ty_def_id), "not an adt")
|
||||||
|
};
|
||||||
|
let name = adt.variant(variant_idx).name;
|
||||||
|
let is_unsized = variant_layout.abi.is_unsized();
|
||||||
|
let is_uninhabited = variant_layout.abi.is_uninhabited();
|
||||||
|
let size = variant_layout.size.bytes() - tag_size;
|
||||||
|
let type_layout_size = TypeLayoutSize { is_unsized, is_uninhabited, size };
|
||||||
|
(name, type_layout_size)
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
Vec::new()
|
||||||
|
};
|
||||||
|
|
||||||
let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| {
|
let type_layout_size = tcx.layout_of(param_env.and(ty)).map(|layout| {
|
||||||
let is_unsized = layout.abi.is_unsized();
|
let is_unsized = layout.abi.is_unsized();
|
||||||
|
@ -90,7 +90,9 @@ impl LocalSourcesCollector<'_, '_> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
let mut href = href.into_inner().to_string_lossy().into_owned();
|
let mut href = href.into_inner().to_string_lossy().into_owned();
|
||||||
if let Some(c) = href.as_bytes().last() && *c != b'/' {
|
if let Some(c) = href.as_bytes().last()
|
||||||
|
&& *c != b'/'
|
||||||
|
{
|
||||||
href.push('/');
|
href.push('/');
|
||||||
}
|
}
|
||||||
let mut src_fname = p.file_name().expect("source has no filename").to_os_string();
|
let mut src_fname = p.file_name().expect("source has no filename").to_os_string();
|
||||||
@ -212,7 +214,9 @@ impl SourceCollector<'_, '_> {
|
|||||||
|
|
||||||
let root_path = PathBuf::from("../../").join(root_path.into_inner());
|
let root_path = PathBuf::from("../../").join(root_path.into_inner());
|
||||||
let mut root_path = root_path.to_string_lossy();
|
let mut root_path = root_path.to_string_lossy();
|
||||||
if let Some(c) = root_path.as_bytes().last() && *c != b'/' {
|
if let Some(c) = root_path.as_bytes().last()
|
||||||
|
&& *c != b'/'
|
||||||
|
{
|
||||||
root_path += "/";
|
root_path += "/";
|
||||||
}
|
}
|
||||||
let mut cur = self.dst.join(cur.into_inner());
|
let mut cur = self.dst.join(cur.into_inner());
|
||||||
|
@ -250,15 +250,16 @@ pub(crate) fn id_from_item_inner(
|
|||||||
// their parent module, which isn't present in the output JSON items. So
|
// their parent module, which isn't present in the output JSON items. So
|
||||||
// instead, we directly get the primitive symbol and convert it to u32 to
|
// instead, we directly get the primitive symbol and convert it to u32 to
|
||||||
// generate the ID.
|
// generate the ID.
|
||||||
if matches!(tcx.def_kind(def_id), DefKind::Mod) &&
|
if matches!(tcx.def_kind(def_id), DefKind::Mod)
|
||||||
let Some(prim) = tcx.get_attrs(*def_id, sym::rustc_doc_primitive)
|
&& let Some(prim) = tcx
|
||||||
.find_map(|attr| attr.value_str()) {
|
.get_attrs(*def_id, sym::rustc_doc_primitive)
|
||||||
|
.find_map(|attr| attr.value_str())
|
||||||
|
{
|
||||||
format!(":{}", prim.as_u32())
|
format!(":{}", prim.as_u32())
|
||||||
} else {
|
} else {
|
||||||
tcx
|
tcx.opt_item_name(*def_id)
|
||||||
.opt_item_name(*def_id)
|
.map(|n| format!(":{}", n.as_u32()))
|
||||||
.map(|n| format!(":{}", n.as_u32()))
|
.unwrap_or_default()
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -80,9 +80,9 @@ impl<'tcx> JsonRenderer<'tcx> {
|
|||||||
// document primitive items in an arbitrary crate by using
|
// document primitive items in an arbitrary crate by using
|
||||||
// `rustc_doc_primitive`.
|
// `rustc_doc_primitive`.
|
||||||
let mut is_primitive_impl = false;
|
let mut is_primitive_impl = false;
|
||||||
if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind &&
|
if let clean::types::ItemKind::ImplItem(ref impl_) = *item.kind
|
||||||
impl_.trait_.is_none() &&
|
&& impl_.trait_.is_none()
|
||||||
let clean::types::Type::Primitive(_) = impl_.for_
|
&& let clean::types::Type::Primitive(_) = impl_.for_
|
||||||
{
|
{
|
||||||
is_primitive_impl = true;
|
is_primitive_impl = true;
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,9 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
|
|||||||
let def_id = item.item_id.expect_def_id().expect_local();
|
let def_id = item.item_id.expect_def_id().expect_local();
|
||||||
|
|
||||||
// check if parent is trait impl
|
// check if parent is trait impl
|
||||||
if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id) &&
|
if let Some(parent_def_id) = cx.tcx.opt_local_parent(def_id)
|
||||||
let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id) &&
|
&& let Some(parent_node) = cx.tcx.hir().find_by_def_id(parent_def_id)
|
||||||
matches!(
|
&& matches!(
|
||||||
parent_node,
|
parent_node,
|
||||||
hir::Node::Item(hir::Item {
|
hir::Node::Item(hir::Item {
|
||||||
kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }),
|
kind: hir::ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }),
|
||||||
|
@ -303,7 +303,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||||||
Res::Def(DefKind::Enum, did) => match tcx.type_of(did).instantiate_identity().kind() {
|
Res::Def(DefKind::Enum, did) => match tcx.type_of(did).instantiate_identity().kind() {
|
||||||
ty::Adt(def, _) if def.is_enum() => {
|
ty::Adt(def, _) if def.is_enum() => {
|
||||||
if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name)
|
if let Some(variant) = def.variants().iter().find(|v| v.name == variant_name)
|
||||||
&& let Some(field) = variant.fields.iter().find(|f| f.name == variant_field_name) {
|
&& let Some(field) =
|
||||||
|
variant.fields.iter().find(|f| f.name == variant_field_name)
|
||||||
|
{
|
||||||
Ok((ty_res, field.did))
|
Ok((ty_res, field.did))
|
||||||
} else {
|
} else {
|
||||||
Err(UnresolvedPath {
|
Err(UnresolvedPath {
|
||||||
@ -973,7 +975,8 @@ impl LinkCollector<'_, '_> {
|
|||||||
&& let Some(def_id) = item.item_id.as_def_id()
|
&& let Some(def_id) = item.item_id.as_def_id()
|
||||||
&& let Some(def_id) = def_id.as_local()
|
&& let Some(def_id) = def_id.as_local()
|
||||||
&& !self.cx.tcx.effective_visibilities(()).is_exported(def_id)
|
&& !self.cx.tcx.effective_visibilities(()).is_exported(def_id)
|
||||||
&& !has_primitive_or_keyword_docs(&item.attrs.other_attrs) {
|
&& !has_primitive_or_keyword_docs(&item.attrs.other_attrs)
|
||||||
|
{
|
||||||
// Skip link resolution for non-exported items.
|
// Skip link resolution for non-exported items.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1250,9 +1253,10 @@ impl LinkCollector<'_, '_> {
|
|||||||
|
|
||||||
// FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether.
|
// FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether.
|
||||||
// However I'm not sure how to check that across crates.
|
// However I'm not sure how to check that across crates.
|
||||||
if let Some(candidate) = candidates.get(0) &&
|
if let Some(candidate) = candidates.get(0)
|
||||||
candidate.0 == Res::Primitive(PrimitiveType::RawPointer) &&
|
&& candidate.0 == Res::Primitive(PrimitiveType::RawPointer)
|
||||||
key.path_str.contains("::") // We only want to check this if this is an associated item.
|
&& key.path_str.contains("::")
|
||||||
|
// We only want to check this if this is an associated item.
|
||||||
{
|
{
|
||||||
if key.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers {
|
if key.item_id.is_local() && !self.cx.tcx.features().intra_doc_pointers {
|
||||||
self.report_rawptr_assoc_feature_gate(diag.dox, &diag.link_range, diag.item);
|
self.report_rawptr_assoc_feature_gate(diag.dox, &diag.link_range, diag.item);
|
||||||
@ -1318,8 +1322,8 @@ impl LinkCollector<'_, '_> {
|
|||||||
for other_ns in [TypeNS, ValueNS, MacroNS] {
|
for other_ns in [TypeNS, ValueNS, MacroNS] {
|
||||||
if other_ns != expected_ns {
|
if other_ns != expected_ns {
|
||||||
if let Ok(res) =
|
if let Ok(res) =
|
||||||
self.resolve(path_str, other_ns, item_id, module_id) &&
|
self.resolve(path_str, other_ns, item_id, module_id)
|
||||||
!res.is_empty()
|
&& !res.is_empty()
|
||||||
{
|
{
|
||||||
err = ResolutionFailure::WrongNamespace {
|
err = ResolutionFailure::WrongNamespace {
|
||||||
res: full_res(self.cx.tcx, res[0]),
|
res: full_res(self.cx.tcx, res[0]),
|
||||||
@ -1892,8 +1896,10 @@ fn resolution_failure(
|
|||||||
};
|
};
|
||||||
let is_struct_variant = |did| {
|
let is_struct_variant = |did| {
|
||||||
if let ty::Adt(def, _) = tcx.type_of(did).instantiate_identity().kind()
|
if let ty::Adt(def, _) = tcx.type_of(did).instantiate_identity().kind()
|
||||||
&& def.is_enum()
|
&& def.is_enum()
|
||||||
&& let Some(variant) = def.variants().iter().find(|v| v.name == res.name(tcx)) {
|
&& let Some(variant) =
|
||||||
|
def.variants().iter().find(|v| v.name == res.name(tcx))
|
||||||
|
{
|
||||||
// ctor is `None` if variant is a struct
|
// ctor is `None` if variant is a struct
|
||||||
variant.ctor.is_none()
|
variant.ctor.is_none()
|
||||||
} else {
|
} else {
|
||||||
|
@ -154,9 +154,9 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
|
|||||||
|
|
||||||
// scan through included items ahead of time to splice in Deref targets to the "valid" sets
|
// scan through included items ahead of time to splice in Deref targets to the "valid" sets
|
||||||
for it in new_items_external.iter().chain(new_items_local.iter()) {
|
for it in new_items_external.iter().chain(new_items_local.iter()) {
|
||||||
if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind &&
|
if let ImplItem(box Impl { ref for_, ref trait_, ref items, .. }) = *it.kind
|
||||||
trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait() &&
|
&& trait_.as_ref().map(|t| t.def_id()) == tcx.lang_items().deref_trait()
|
||||||
cleaner.keep_impl(for_, true)
|
&& cleaner.keep_impl(for_, true)
|
||||||
{
|
{
|
||||||
let target = items
|
let target = items
|
||||||
.iter()
|
.iter()
|
||||||
@ -250,8 +250,8 @@ impl<'cache> DocVisitor for ItemAndAliasCollector<'cache> {
|
|||||||
fn visit_item(&mut self, i: &Item) {
|
fn visit_item(&mut self, i: &Item) {
|
||||||
self.items.insert(i.item_id);
|
self.items.insert(i.item_id);
|
||||||
|
|
||||||
if let TypeAliasItem(alias) = &*i.kind &&
|
if let TypeAliasItem(alias) = &*i.kind
|
||||||
let Some(did) = alias.type_.def_id(self.cache)
|
&& let Some(did) = alias.type_.def_id(self.cache)
|
||||||
{
|
{
|
||||||
self.items.insert(ItemId::DefId(did));
|
self.items.insert(ItemId::DefId(did));
|
||||||
}
|
}
|
||||||
|
@ -213,7 +213,9 @@ fn extract_path_backwards(text: &str, end_pos: usize) -> Option<usize> {
|
|||||||
.take_while(|(_, c)| is_id_start(*c) || is_id_continue(*c))
|
.take_while(|(_, c)| is_id_start(*c) || is_id_continue(*c))
|
||||||
.reduce(|_accum, item| item)
|
.reduce(|_accum, item| item)
|
||||||
.and_then(|(new_pos, c)| is_id_start(c).then_some(new_pos));
|
.and_then(|(new_pos, c)| is_id_start(c).then_some(new_pos));
|
||||||
if let Some(new_pos) = new_pos && current_pos != new_pos {
|
if let Some(new_pos) = new_pos
|
||||||
|
&& current_pos != new_pos
|
||||||
|
{
|
||||||
current_pos = new_pos;
|
current_pos = new_pos;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -208,24 +208,25 @@ impl<'a> DocFolder for ImplStripper<'a, '_> {
|
|||||||
// Because we don't inline in `maybe_inline_local` if the output format is JSON,
|
// Because we don't inline in `maybe_inline_local` if the output format is JSON,
|
||||||
// we need to make a special check for JSON output: we want to keep it unless it has
|
// we need to make a special check for JSON output: we want to keep it unless it has
|
||||||
// a `#[doc(hidden)]` attribute if the `for_` type is exported.
|
// a `#[doc(hidden)]` attribute if the `for_` type is exported.
|
||||||
if let Some(did) = imp.for_.def_id(self.cache) &&
|
if let Some(did) = imp.for_.def_id(self.cache)
|
||||||
!imp.for_.is_assoc_ty() && !self.should_keep_impl(&i, did)
|
&& !imp.for_.is_assoc_ty()
|
||||||
|
&& !self.should_keep_impl(&i, did)
|
||||||
{
|
{
|
||||||
debug!("ImplStripper: impl item for stripped type; removing");
|
debug!("ImplStripper: impl item for stripped type; removing");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id()) &&
|
if let Some(did) = imp.trait_.as_ref().map(|t| t.def_id())
|
||||||
!self.should_keep_impl(&i, did) {
|
&& !self.should_keep_impl(&i, did)
|
||||||
|
{
|
||||||
debug!("ImplStripper: impl item for stripped trait; removing");
|
debug!("ImplStripper: impl item for stripped trait; removing");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
|
if let Some(generics) = imp.trait_.as_ref().and_then(|t| t.generics()) {
|
||||||
for typaram in generics {
|
for typaram in generics {
|
||||||
if let Some(did) = typaram.def_id(self.cache) && !self.should_keep_impl(&i, did)
|
if let Some(did) = typaram.def_id(self.cache)
|
||||||
|
&& !self.should_keep_impl(&i, did)
|
||||||
{
|
{
|
||||||
debug!(
|
debug!("ImplStripper: stripped item in trait's generics; removing impl");
|
||||||
"ImplStripper: stripped item in trait's generics; removing impl"
|
|
||||||
);
|
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,14 +135,16 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
|
|||||||
// macro in the same module.
|
// macro in the same module.
|
||||||
let mut inserted = FxHashSet::default();
|
let mut inserted = FxHashSet::default();
|
||||||
for child in self.cx.tcx.module_children_local(CRATE_DEF_ID) {
|
for child in self.cx.tcx.module_children_local(CRATE_DEF_ID) {
|
||||||
if !child.reexport_chain.is_empty() &&
|
if !child.reexport_chain.is_empty()
|
||||||
let Res::Def(DefKind::Macro(_), def_id) = child.res &&
|
&& let Res::Def(DefKind::Macro(_), def_id) = child.res
|
||||||
let Some(local_def_id) = def_id.as_local() &&
|
&& let Some(local_def_id) = def_id.as_local()
|
||||||
self.cx.tcx.has_attr(def_id, sym::macro_export) &&
|
&& self.cx.tcx.has_attr(def_id, sym::macro_export)
|
||||||
inserted.insert(def_id)
|
&& inserted.insert(def_id)
|
||||||
{
|
{
|
||||||
let item = self.cx.tcx.hir().expect_item(local_def_id);
|
let item = self.cx.tcx.hir().expect_item(local_def_id);
|
||||||
top_level_module.items.insert((local_def_id, Some(item.ident.name)), (item, None, None));
|
top_level_module
|
||||||
|
.items
|
||||||
|
.insert((local_def_id, Some(item.ident.name)), (item, None, None));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3701,9 +3701,7 @@ impl<'test> TestCx<'test> {
|
|||||||
let stderr_bits = format!("{}bit.stderr", self.config.get_pointer_width());
|
let stderr_bits = format!("{}bit.stderr", self.config.get_pointer_width());
|
||||||
let (stderr_kind, stdout_kind) = match output_kind {
|
let (stderr_kind, stdout_kind) = match output_kind {
|
||||||
TestOutput::Compile => (
|
TestOutput::Compile => (
|
||||||
{
|
{ if self.props.stderr_per_bitwidth { &stderr_bits } else { UI_STDERR } },
|
||||||
if self.props.stderr_per_bitwidth { &stderr_bits } else { UI_STDERR }
|
|
||||||
},
|
|
||||||
UI_STDOUT,
|
UI_STDOUT,
|
||||||
),
|
),
|
||||||
TestOutput::Run => (UI_RUN_STDERR, UI_RUN_STDOUT),
|
TestOutput::Run => (UI_RUN_STDERR, UI_RUN_STDOUT),
|
||||||
|
Loading…
Reference in New Issue
Block a user