Auto merge of #89683 - GuillaumeGomez:rollup-q2mjd9m, r=GuillaumeGomez
Rollup of 6 pull requests Successful merges: - #86506 (Don't normalize xform_ret_ty during method candidate assembly ) - #89538 (Make rustdoc not highlight `->` and `=>` as operators) - #89649 (clippy::complexity fixes) - #89668 (Cfg hide more conditions for core and alloc) - #89669 (Remove special-casing of never primitive in rustdoc-json-types) - #89672 (Remove unwrap_or! macro) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
f8751436ff
@ -20,16 +20,6 @@
|
||||
#[macro_use]
|
||||
extern crate rustc_macros;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! unwrap_or {
|
||||
($opt:expr, $default:expr) => {
|
||||
match $opt {
|
||||
Some(x) => x,
|
||||
None => $default,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub mod util {
|
||||
pub mod classify;
|
||||
pub mod comments;
|
||||
|
@ -1345,8 +1345,7 @@ pub(super) fn lower_generics_mut(
|
||||
generics
|
||||
.params
|
||||
.iter()
|
||||
.find(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
|
||||
.is_some()
|
||||
.any(|p| def_id == self.resolver.local_def_id(p.id).to_def_id())
|
||||
}
|
||||
// Either the `bounded_ty` is not a plain type parameter, or
|
||||
// it's not found in the generic type parameters list.
|
||||
|
@ -201,7 +201,7 @@ fn precompute_borrows_out_of_scope(
|
||||
let bb_data = &self.body[bb];
|
||||
debug_assert!(hi == bb_data.statements.len());
|
||||
for &succ_bb in bb_data.terminator().successors() {
|
||||
if self.visited.insert(succ_bb) == false {
|
||||
if !self.visited.insert(succ_bb) {
|
||||
if succ_bb == location.block && first_lo > 0 {
|
||||
// `succ_bb` has been seen before. If it wasn't
|
||||
// fully processed, add its first part to `stack`
|
||||
|
@ -972,8 +972,7 @@ fn suggest_ampmut<'tcx>(
|
||||
if let Some(assignment_rhs_span) = opt_assignment_rhs_span {
|
||||
if let Ok(src) = tcx.sess.source_map().span_to_snippet(assignment_rhs_span) {
|
||||
let is_mutbl = |ty: &str| -> bool {
|
||||
if ty.starts_with("mut") {
|
||||
let rest = &ty[3..];
|
||||
if let Some(rest) = ty.strip_prefix("mut") {
|
||||
match rest.chars().next() {
|
||||
// e.g. `&mut x`
|
||||
Some(c) if c.is_whitespace() => true,
|
||||
|
@ -594,7 +594,7 @@ fn create_derived_impl(
|
||||
GenericParamKind::Const { ty, kw_span, .. } => {
|
||||
let const_nodefault_kind = GenericParamKind::Const {
|
||||
ty: ty.clone(),
|
||||
kw_span: kw_span.clone(),
|
||||
kw_span: *kw_span,
|
||||
|
||||
// We can't have default values inside impl block
|
||||
default: None,
|
||||
|
@ -130,8 +130,8 @@ fn emit_associated_type_err(
|
||||
.tcx()
|
||||
.sess
|
||||
.struct_span_err(span, &format!("`impl` associated type signature for `{}` doesn't match `trait` associated type signature", item_name));
|
||||
err.span_label(impl_sp, &format!("found"));
|
||||
err.span_label(trait_sp, &format!("expected"));
|
||||
err.span_label(impl_sp, "found");
|
||||
err.span_label(trait_sp, "expected");
|
||||
|
||||
err.emit();
|
||||
}
|
||||
|
@ -1,7 +1,6 @@
|
||||
use crate::context::{CheckLintNameResult, LintStore};
|
||||
use crate::late::unerased_lint_store;
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::unwrap_or;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
|
||||
@ -233,7 +232,10 @@ pub(crate) fn push(
|
||||
Some(lvl) => lvl,
|
||||
};
|
||||
|
||||
let mut metas = unwrap_or!(attr.meta_item_list(), continue);
|
||||
let mut metas = match attr.meta_item_list() {
|
||||
Some(x) => x,
|
||||
None => continue,
|
||||
};
|
||||
|
||||
if metas.is_empty() {
|
||||
// FIXME (#55112): issue unused-attributes lint for `#[level()]`
|
||||
|
@ -230,8 +230,7 @@ fn check_panic_str<'tcx>(
|
||||
Err(_) => (None, None),
|
||||
};
|
||||
|
||||
let mut fmt_parser =
|
||||
Parser::new(fmt.as_ref(), style, snippet.clone(), false, ParseMode::Format);
|
||||
let mut fmt_parser = Parser::new(fmt, style, snippet.clone(), false, ParseMode::Format);
|
||||
let n_arguments = (&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
|
||||
|
||||
if n_arguments > 0 && fmt_parser.errors.is_empty() {
|
||||
|
@ -363,7 +363,7 @@ fn process_command_line(&mut self) {
|
||||
.collect::<Vec<_>>();
|
||||
if existing.is_empty() {
|
||||
// Add if not found
|
||||
let new_name = passed_lib.new_name.as_ref().map(|s| &**s); // &Option<String> -> Option<&str>
|
||||
let new_name: Option<&str> = passed_lib.new_name.as_deref();
|
||||
let lib = NativeLib {
|
||||
name: Some(Symbol::intern(new_name.unwrap_or(&passed_lib.name))),
|
||||
kind: passed_lib.kind,
|
||||
|
@ -986,7 +986,7 @@ fn layout_of_uncached(&self, ty: Ty<'tcx>) -> Result<&'tcx Layout, LayoutError<'
|
||||
let niche = if def.repr.hide_niche() {
|
||||
None
|
||||
} else {
|
||||
Niche::from_scalar(dl, Size::ZERO, scalar.clone())
|
||||
Niche::from_scalar(dl, Size::ZERO, *scalar)
|
||||
};
|
||||
if let Some(niche) = niche {
|
||||
match st.largest_niche {
|
||||
@ -2273,7 +2273,7 @@ fn field_ty_or_layout(
|
||||
) -> TyMaybeWithLayout<'tcx> {
|
||||
let tcx = cx.tcx();
|
||||
let tag_layout = |tag: Scalar| -> TyAndLayout<'tcx> {
|
||||
let layout = Layout::scalar(cx, tag.clone());
|
||||
let layout = Layout::scalar(cx, tag);
|
||||
TyAndLayout { layout: tcx.intern_layout(layout), ty: tag.value.to_ty(tcx) }
|
||||
};
|
||||
|
||||
|
@ -130,7 +130,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
TerminatorKind::Call {
|
||||
func: exchange_malloc,
|
||||
args: vec![Operand::Move(size), Operand::Move(align)],
|
||||
destination: Some((Place::from(storage), success)),
|
||||
destination: Some((storage, success)),
|
||||
cleanup: None,
|
||||
from_hir_call: false,
|
||||
fn_span: expr_span,
|
||||
@ -153,7 +153,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Transmute `*mut u8` to the box (thus far, uninitialized):
|
||||
let box_ = Rvalue::ShallowInitBox(Operand::Move(Place::from(storage)), value.ty);
|
||||
let box_ = Rvalue::ShallowInitBox(Operand::Move(storage), value.ty);
|
||||
this.cfg.push_assign(block, source_info, Place::from(result), box_);
|
||||
|
||||
// initialize the box contents:
|
||||
|
@ -1068,9 +1068,7 @@ pub(super) fn iter_missing<'a, 'p>(
|
||||
Missing {
|
||||
nonexhaustive_enum_missing_real_variants: self
|
||||
.iter_missing(pcx)
|
||||
.filter(|c| !c.is_non_exhaustive())
|
||||
.next()
|
||||
.is_some(),
|
||||
.any(|c| !c.is_non_exhaustive()),
|
||||
}
|
||||
} else {
|
||||
Missing { nonexhaustive_enum_missing_real_variants: false }
|
||||
|
@ -263,7 +263,7 @@ fn find_discriminant_switch_pairing(
|
||||
}
|
||||
|
||||
// check that the value being matched on is the same. The
|
||||
if this_bb_discr_info.targets_with_values.iter().find(|x| x.0 == value).is_none() {
|
||||
if !this_bb_discr_info.targets_with_values.iter().any(|x| x.0 == value) {
|
||||
trace!("NO: values being matched on are not the same");
|
||||
return None;
|
||||
}
|
||||
|
@ -111,8 +111,7 @@ fn patch_expand_statement(
|
||||
Operand::Copy(place) | Operand::Move(place) => {
|
||||
// create new local
|
||||
let ty = operand.ty(self.local_decls, self.tcx);
|
||||
let local_decl =
|
||||
LocalDecl::with_source_info(ty, statement.source_info.clone());
|
||||
let local_decl = LocalDecl::with_source_info(ty, statement.source_info);
|
||||
let local = self.local_decls.push(local_decl);
|
||||
// make it live
|
||||
let mut make_live_statement = statement.clone();
|
||||
|
@ -1767,8 +1767,7 @@ fn check_macro_use(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||
fn check_macro_export(&self, hir_id: HirId, attr: &Attribute, target: Target) {
|
||||
if target != Target::MacroDef {
|
||||
self.tcx.struct_span_lint_hir(UNUSED_ATTRIBUTES, hir_id, attr.span, |lint| {
|
||||
lint.build(&format!("`#[macro_export]` only has an effect on macro definitions"))
|
||||
.emit();
|
||||
lint.build("`#[macro_export]` only has an effect on macro definitions").emit();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -9,7 +9,6 @@
|
||||
use crate::{CrateLint, Module, ModuleOrUniformRoot, ParentScope, PerNS, ScopeSet, Weak};
|
||||
use crate::{NameBinding, NameBindingKind, PathResult, PrivacyError, ToNameBinding};
|
||||
|
||||
use rustc_ast::unwrap_or;
|
||||
use rustc_ast::NodeId;
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_data_structures::ptr_key::PtrKey;
|
||||
@ -349,10 +348,10 @@ impl<'a> Resolver<'a> {
|
||||
if !self.is_accessible_from(single_import.vis.get(), parent_scope.module) {
|
||||
continue;
|
||||
}
|
||||
let module = unwrap_or!(
|
||||
single_import.imported_module.get(),
|
||||
return Err((Undetermined, Weak::No))
|
||||
);
|
||||
let module = match single_import.imported_module.get() {
|
||||
Some(x) => x,
|
||||
None => return Err((Undetermined, Weak::No)),
|
||||
};
|
||||
let ident = match single_import.kind {
|
||||
ImportKind::Single { source, .. } => source,
|
||||
_ => unreachable!(),
|
||||
|
@ -278,14 +278,14 @@ fn thir(&self) -> &'a thir::Thir<'tcx> {
|
||||
|
||||
fn visit_expr(&mut self, expr: &thir::Expr<'tcx>) {
|
||||
self.is_poly |= expr.ty.definitely_has_param_types_or_consts(self.tcx);
|
||||
if self.is_poly == false {
|
||||
if !self.is_poly {
|
||||
visit::walk_expr(self, expr)
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_pat(&mut self, pat: &thir::Pat<'tcx>) {
|
||||
self.is_poly |= pat.ty.definitely_has_param_types_or_consts(self.tcx);
|
||||
if self.is_poly == false {
|
||||
if !self.is_poly {
|
||||
visit::walk_pat(self, pat);
|
||||
}
|
||||
}
|
||||
@ -298,7 +298,7 @@ fn visit_const(&mut self, ct: &'tcx ty::Const<'tcx>) {
|
||||
let mut is_poly_vis = IsThirPolymorphic { is_poly: false, thir: body, tcx };
|
||||
visit::walk_expr(&mut is_poly_vis, &body[body_id]);
|
||||
debug!("AbstractConstBuilder: is_poly={}", is_poly_vis.is_poly);
|
||||
if is_poly_vis.is_poly == false {
|
||||
if !is_poly_vis.is_poly {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
|
@ -892,7 +892,7 @@ fn visit_region(&mut self, r: Region<'tcx>) -> ControlFlow<Self::BreakTy> {
|
||||
match r {
|
||||
ty::ReLateBound(index, br) if *index == self.binder_index => match br.kind {
|
||||
ty::BoundRegionKind::BrNamed(def_id, _name) => {
|
||||
if self.named_parameters.iter().find(|d| **d == def_id).is_none() {
|
||||
if !self.named_parameters.iter().any(|d| *d == def_id) {
|
||||
self.named_parameters.push(def_id);
|
||||
}
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ fn confirm_builtin_call(
|
||||
let obligation = Obligation::new(
|
||||
ObligationCause::dummy_with_span(callee_expr.span),
|
||||
self.param_env,
|
||||
predicate.clone(),
|
||||
*predicate,
|
||||
);
|
||||
let result = self.infcx.evaluate_obligation(&obligation);
|
||||
self.tcx
|
||||
|
@ -753,17 +753,27 @@ fn assemble_inherent_impl_probe(&mut self, impl_def_id: DefId) {
|
||||
let (impl_ty, impl_substs) = self.impl_ty_and_substs(impl_def_id);
|
||||
let impl_ty = impl_ty.subst(self.tcx, impl_substs);
|
||||
|
||||
debug!("impl_ty: {:?}", impl_ty);
|
||||
|
||||
// Determine the receiver type that the method itself expects.
|
||||
let xform_tys = self.xform_self_ty(&item, impl_ty, impl_substs);
|
||||
let (xform_self_ty, xform_ret_ty) = self.xform_self_ty(&item, impl_ty, impl_substs);
|
||||
debug!("xform_self_ty: {:?}, xform_ret_ty: {:?}", xform_self_ty, xform_ret_ty);
|
||||
|
||||
// We can't use normalize_associated_types_in as it will pollute the
|
||||
// fcx's fulfillment context after this probe is over.
|
||||
// Note: we only normalize `xform_self_ty` here since the normalization
|
||||
// of the return type can lead to inference results that prohibit
|
||||
// valid canidates from being found, see issue #85671
|
||||
// FIXME Postponing the normalization of the return type likely only hides a deeper bug,
|
||||
// which might be caused by the `param_env` itself. The clauses of the `param_env`
|
||||
// maybe shouldn't include `Param`s, but rather fresh variables or be canonicalized,
|
||||
// see isssue #89650
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
let selcx = &mut traits::SelectionContext::new(self.fcx);
|
||||
let traits::Normalized { value: (xform_self_ty, xform_ret_ty), obligations } =
|
||||
traits::normalize(selcx, self.param_env, cause, xform_tys);
|
||||
let traits::Normalized { value: xform_self_ty, obligations } =
|
||||
traits::normalize(selcx, self.param_env, cause, xform_self_ty);
|
||||
debug!(
|
||||
"assemble_inherent_impl_probe: xform_self_ty = {:?}/{:?}",
|
||||
"assemble_inherent_impl_probe after normalization: xform_self_ty = {:?}/{:?}",
|
||||
xform_self_ty, xform_ret_ty
|
||||
);
|
||||
|
||||
@ -1420,6 +1430,9 @@ fn consider_probe(
|
||||
};
|
||||
|
||||
let mut result = ProbeResult::Match;
|
||||
let mut xform_ret_ty = probe.xform_ret_ty;
|
||||
debug!(?xform_ret_ty);
|
||||
|
||||
let selcx = &mut traits::SelectionContext::new(self);
|
||||
let cause = traits::ObligationCause::misc(self.span, self.body_id);
|
||||
|
||||
@ -1428,7 +1441,17 @@ fn consider_probe(
|
||||
// match as well (or at least may match, sometimes we
|
||||
// don't have enough information to fully evaluate).
|
||||
match probe.kind {
|
||||
InherentImplCandidate(substs, ref ref_obligations) => {
|
||||
InherentImplCandidate(ref substs, ref ref_obligations) => {
|
||||
// `xform_ret_ty` hasn't been normalized yet, only `xform_self_ty`,
|
||||
// see the reasons mentioned in the comments in `assemble_inherent_impl_probe`
|
||||
// for why this is necessary
|
||||
let traits::Normalized {
|
||||
value: normalized_xform_ret_ty,
|
||||
obligations: normalization_obligations,
|
||||
} = traits::normalize(selcx, self.param_env, cause.clone(), probe.xform_ret_ty);
|
||||
xform_ret_ty = normalized_xform_ret_ty;
|
||||
debug!("xform_ret_ty after normalization: {:?}", xform_ret_ty);
|
||||
|
||||
// Check whether the impl imposes obligations we have to worry about.
|
||||
let impl_def_id = probe.item.container.id();
|
||||
let impl_bounds = self.tcx.predicates_of(impl_def_id);
|
||||
@ -1442,7 +1465,9 @@ fn consider_probe(
|
||||
|
||||
let candidate_obligations = impl_obligations
|
||||
.chain(norm_obligations.into_iter())
|
||||
.chain(ref_obligations.iter().cloned());
|
||||
.chain(ref_obligations.iter().cloned())
|
||||
.chain(normalization_obligations.into_iter());
|
||||
|
||||
// Evaluate those obligations to see if they might possibly hold.
|
||||
for o in candidate_obligations {
|
||||
let o = self.resolve_vars_if_possible(o);
|
||||
@ -1527,9 +1552,7 @@ fn consider_probe(
|
||||
}
|
||||
|
||||
if let ProbeResult::Match = result {
|
||||
if let (Some(return_ty), Some(xform_ret_ty)) =
|
||||
(self.return_type, probe.xform_ret_ty)
|
||||
{
|
||||
if let (Some(return_ty), Some(xform_ret_ty)) = (self.return_type, xform_ret_ty) {
|
||||
let xform_ret_ty = self.resolve_vars_if_possible(xform_ret_ty);
|
||||
debug!(
|
||||
"comparing return_ty {:?} with xform ret ty {:?}",
|
||||
@ -1669,6 +1692,7 @@ fn record_static_candidate(&mut self, source: CandidateSource) {
|
||||
self.static_candidates.push(source);
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn xform_self_ty(
|
||||
&self,
|
||||
item: &ty::AssocItem,
|
||||
@ -1683,9 +1707,10 @@ fn xform_self_ty(
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self))]
|
||||
fn xform_method_sig(&self, method: DefId, substs: SubstsRef<'tcx>) -> ty::FnSig<'tcx> {
|
||||
let fn_sig = self.tcx.fn_sig(method);
|
||||
debug!("xform_self_ty(fn_sig={:?}, substs={:?})", fn_sig, substs);
|
||||
debug!(?fn_sig);
|
||||
|
||||
assert!(!substs.has_escaping_bound_vars());
|
||||
|
||||
|
@ -413,7 +413,7 @@ fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
|
||||
}
|
||||
|
||||
hir::ExprKind::Match(ref discr, arms, _) => {
|
||||
self.link_match(discr, &arms[..]);
|
||||
self.link_match(discr, arms);
|
||||
|
||||
intravisit::walk_expr(self, expr);
|
||||
}
|
||||
|
@ -69,7 +69,12 @@
|
||||
)]
|
||||
#![cfg_attr(
|
||||
not(bootstrap),
|
||||
doc(cfg_hide(not(test), not(any(test, bootstrap)), target_has_atomic = "ptr"))
|
||||
doc(cfg_hide(
|
||||
not(test),
|
||||
not(any(test, bootstrap)),
|
||||
any(not(feature = "miri-test-libstd"), test, doctest),
|
||||
target_has_atomic = "ptr"
|
||||
))
|
||||
)]
|
||||
#![no_std]
|
||||
#![needs_allocator]
|
||||
|
@ -64,6 +64,7 @@
|
||||
not(bootstrap),
|
||||
doc(cfg_hide(
|
||||
not(test),
|
||||
any(not(feature = "miri-test-libstd"), test, doctest),
|
||||
target_pointer_width = "16",
|
||||
target_pointer_width = "32",
|
||||
target_pointer_width = "64",
|
||||
|
@ -435,7 +435,27 @@ fn advance(
|
||||
_ => Class::RefKeyWord,
|
||||
},
|
||||
|
||||
// Operators.
|
||||
// These can either be operators, or arrows.
|
||||
TokenKind::Eq => match lookahead {
|
||||
Some(TokenKind::Eq) => {
|
||||
self.next();
|
||||
sink(Highlight::Token { text: "==", class: Some(Class::Op) });
|
||||
return;
|
||||
}
|
||||
Some(TokenKind::Gt) => {
|
||||
self.next();
|
||||
sink(Highlight::Token { text: "=>", class: None });
|
||||
return;
|
||||
}
|
||||
_ => Class::Op,
|
||||
},
|
||||
TokenKind::Minus if lookahead == Some(TokenKind::Gt) => {
|
||||
self.next();
|
||||
sink(Highlight::Token { text: "->", class: None });
|
||||
return;
|
||||
}
|
||||
|
||||
// Other operators.
|
||||
TokenKind::Minus
|
||||
| TokenKind::Plus
|
||||
| TokenKind::Or
|
||||
@ -443,7 +463,6 @@ fn advance(
|
||||
| TokenKind::Caret
|
||||
| TokenKind::Percent
|
||||
| TokenKind::Bang
|
||||
| TokenKind::Eq
|
||||
| TokenKind::Lt
|
||||
| TokenKind::Gt => Class::Op,
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
<span class="kw">use</span> <span class="ident">std::path</span>::{<span class="ident">Path</span>, <span class="ident">PathBuf</span>};
|
||||
|
||||
<span class="attribute">#[<span class="ident">cfg</span>(<span class="ident">target_os</span> <span class="op">=</span> <span class="string">"linux"</span>)]</span>
|
||||
<span class="kw">fn</span> <span class="ident">main</span>() {
|
||||
<span class="kw">fn</span> <span class="ident">main</span>() -> () {
|
||||
<span class="kw">let</span> <span class="ident">foo</span> <span class="op">=</span> <span class="bool-val">true</span> <span class="op">&&</span> <span class="bool-val">false</span> <span class="op">|</span><span class="op">|</span> <span class="bool-val">true</span>;
|
||||
<span class="kw">let</span> <span class="kw">_</span>: <span class="kw-2">*</span><span class="kw">const</span> () <span class="op">=</span> <span class="number">0</span>;
|
||||
<span class="kw">let</span> <span class="kw">_</span> <span class="op">=</span> <span class="kw-2">&</span><span class="ident">foo</span>;
|
||||
@ -27,11 +27,11 @@
|
||||
<span class="kw">let</span> <span class="kw-2">mut</span> <span class="ident">s</span> <span class="op">=</span> <span class="ident">String::new</span>();
|
||||
|
||||
<span class="kw">match</span> <span class="kw-2">&</span><span class="ident">s</span> {
|
||||
<span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> <span class="op">=</span><span class="op">></span> {}
|
||||
<span class="kw-2">ref</span> <span class="kw-2">mut</span> <span class="ident">x</span> => {}
|
||||
}
|
||||
}
|
||||
|
||||
<span class="macro">macro_rules!</span> <span class="ident">bar</span> {
|
||||
(<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) <span class="op">=</span><span class="op">></span> {};
|
||||
(<span class="macro-nonterminal">$</span><span class="macro-nonterminal">foo</span>:<span class="ident">tt</span>) => {};
|
||||
}
|
||||
</code></pre>
|
||||
|
@ -3,7 +3,7 @@
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
fn main() {
|
||||
fn main() -> () {
|
||||
let foo = true && false || true;
|
||||
let _: *const () = 0;
|
||||
let _ = &foo;
|
||||
|
@ -418,7 +418,6 @@ fn from_tcx(ty: clean::Type, tcx: TyCtxt<'_>) -> Self {
|
||||
}
|
||||
}
|
||||
Generic(s) => Type::Generic(s.to_string()),
|
||||
Primitive(clean::PrimitiveType::Never) => Type::Never,
|
||||
Primitive(p) => Type::Primitive(p.as_sym().to_string()),
|
||||
BareFunction(f) => Type::FunctionPointer(Box::new((*f).into_tcx(tcx))),
|
||||
Tuple(t) => Type::Tuple(t.into_iter().map(|x| x.into_tcx(tcx)).collect()),
|
||||
|
@ -207,7 +207,7 @@ fn after_krate(&mut self) -> Result<(), Error> {
|
||||
debug!("Done with crate");
|
||||
|
||||
for primitive in Rc::clone(&self.cache).primitive_locations.values() {
|
||||
self.get_impls(primitive.clone());
|
||||
self.get_impls(*primitive);
|
||||
}
|
||||
|
||||
let mut index = (*self.index).clone().into_inner();
|
||||
@ -255,7 +255,7 @@ fn after_krate(&mut self) -> Result<(), Error> {
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
format_version: 8,
|
||||
format_version: 9,
|
||||
};
|
||||
let mut p = self.out_path.clone();
|
||||
p.push(output.index.get(&output.root).unwrap().name.clone().unwrap());
|
||||
|
@ -388,8 +388,6 @@ pub enum Type {
|
||||
},
|
||||
/// `impl TraitA + TraitB + ...`
|
||||
ImplTrait(Vec<GenericBound>),
|
||||
/// `!`
|
||||
Never,
|
||||
/// `_`
|
||||
Infer,
|
||||
/// `*mut u32`, `*u8`, etc.
|
||||
|
22
src/test/rustdoc-json/primitives.rs
Normal file
22
src/test/rustdoc-json/primitives.rs
Normal file
@ -0,0 +1,22 @@
|
||||
#![feature(never_type)]
|
||||
|
||||
// @has primitives.json "$.index[*][?(@.name=='PrimNever')].visibility" \"public\"
|
||||
// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.kind" \"primitive\"
|
||||
// @has - "$.index[*][?(@.name=='PrimNever')].inner.type.inner" \"never\"
|
||||
pub type PrimNever = !;
|
||||
|
||||
// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.kind" \"primitive\"
|
||||
// @has - "$.index[*][?(@.name=='PrimStr')].inner.type.inner" \"str\"
|
||||
pub type PrimStr = str;
|
||||
|
||||
// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.kind" \"primitive\"
|
||||
// @has - "$.index[*][?(@.name=='PrimBool')].inner.type.inner" \"bool\"
|
||||
pub type PrimBool = bool;
|
||||
|
||||
// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.kind" \"primitive\"
|
||||
// @has - "$.index[*][?(@.name=='PrimChar')].inner.type.inner" \"char\"
|
||||
pub type PrimChar = char;
|
||||
|
||||
// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.kind" \"primitive\"
|
||||
// @has - "$.index[*][?(@.name=='PrimU8')].inner.type.inner" \"u8\"
|
||||
pub type PrimU8 = u8;
|
@ -6,37 +6,31 @@
|
||||
// @has 'foo/macro.todo.html'
|
||||
// @has - '//span[@class="macro"]' 'macro_rules!'
|
||||
// @has - '//span[@class="ident"]' 'todo'
|
||||
// Note: count = 2 * ('=' + '>') + '+' = 2 * (1 + 1) + 1 = 5
|
||||
// @count - '//pre[@class="rust macro"]//span[@class="op"]' 5
|
||||
// Note: the only op is the `+`
|
||||
// @count - '//pre[@class="rust macro"]//span[@class="op"]' 1
|
||||
|
||||
// @has - '{ ()'
|
||||
// @has - '//span[@class="op"]' '='
|
||||
// @has - '//span[@class="op"]' '>'
|
||||
// @has - '{ ... };'
|
||||
|
||||
// @has - '($('
|
||||
// @has - '{ () => { ... }; ($('
|
||||
// @has - '//span[@class="macro-nonterminal"]' '$'
|
||||
// @has - '//span[@class="macro-nonterminal"]' 'arg'
|
||||
// @has - ':'
|
||||
// @has - '//span[@class="ident"]' 'tt'
|
||||
// @has - '),'
|
||||
// @has - '//span[@class="op"]' '+'
|
||||
// @has - ')'
|
||||
// @has - ') => { ... }; }'
|
||||
pub use std::todo;
|
||||
|
||||
mod mod1 {
|
||||
// @has 'foo/macro.macro1.html'
|
||||
// @has - 'macro_rules!'
|
||||
// @has - 'macro1'
|
||||
// @has - '{ ()'
|
||||
// @has - '($('
|
||||
// @has - '{ () => { ... }; ($('
|
||||
// @has - '//span[@class="macro-nonterminal"]' '$'
|
||||
// @has - '//span[@class="macro-nonterminal"]' 'arg'
|
||||
// @has - ':'
|
||||
// @has - 'expr'
|
||||
// @has - '),'
|
||||
// @has - '+'
|
||||
// @has - ')'
|
||||
// @has - ') => { ... }; }'
|
||||
#[macro_export]
|
||||
macro_rules! macro1 {
|
||||
() => {};
|
||||
|
@ -6,7 +6,6 @@ LL | let _result = &Some(42).as_deref();
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`{integer}: Deref`
|
||||
`<{integer} as Deref>::Target = _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -6,7 +6,7 @@ LL | let _result = &mut Some(42).as_deref_mut();
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`{integer}: DerefMut`
|
||||
`<{integer} as Deref>::Target = _`
|
||||
`{integer}: Deref`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -6,7 +6,6 @@ LL | let _result = &Ok(42).as_deref();
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`{integer}: Deref`
|
||||
`<{integer} as Deref>::Target = _`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
@ -6,7 +6,7 @@ LL | let _result = &mut Ok(42).as_deref_mut();
|
||||
|
|
||||
= note: the following trait bounds were not satisfied:
|
||||
`{integer}: DerefMut`
|
||||
`<{integer} as Deref>::Target = _`
|
||||
`{integer}: Deref`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
|
37
src/test/ui/resolve/issue-85671.rs
Normal file
37
src/test/ui/resolve/issue-85671.rs
Normal file
@ -0,0 +1,37 @@
|
||||
// check-pass
|
||||
|
||||
// Some trait with a function that returns a slice:
|
||||
pub trait AsSlice {
|
||||
type Element;
|
||||
fn as_slice(&self) -> &[Self::Element];
|
||||
}
|
||||
|
||||
// Some type
|
||||
pub struct A<Cont>(Cont);
|
||||
|
||||
// Here we say that if A wraps a slice, then it implements AsSlice
|
||||
impl<'a, Element> AsSlice for A<&'a [Element]> {
|
||||
type Element = Element;
|
||||
fn as_slice(&self) -> &[Self::Element] {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl<Cont> A<Cont> {
|
||||
// We want this function to work
|
||||
pub fn failing<Coef>(&self)
|
||||
where
|
||||
Self: AsSlice<Element = Coef>,
|
||||
{
|
||||
self.as_ref_a().as_ref_a();
|
||||
}
|
||||
|
||||
pub fn as_ref_a<Coef>(&self) -> A<&[<Self as AsSlice>::Element]>
|
||||
where
|
||||
Self: AsSlice<Element = Coef>,
|
||||
{
|
||||
A(self.as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
Loading…
Reference in New Issue
Block a user