Auto merge of #80510 - JohnTitor:rollup-gow7y0l, r=JohnTitor

Rollup of 7 pull requests

Successful merges:

 - #80185 (Fix ICE when pointing at multi bytes character)
 - #80260 (slightly more typed interface to panic implementation)
 - #80311 (Improvements to NatVis support)
 - #80337 (Use `desc` as a doc-comment for queries if there are no doc comments)
 - #80381 (Revert "Cleanup markdown span handling")
 - #80492 (remove empty wraps, don't return Results from from infallible functions)
 - #80509 (where possible, pass slices instead of &Vec or &String (clippy::ptr_arg))

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2020-12-30 15:30:56 +00:00
commit 507bff92fa
45 changed files with 384 additions and 276 deletions

View File

@ -485,7 +485,7 @@ pub(crate) unsafe fn optimize(
diag_handler: &Handler,
module: &ModuleCodegen<ModuleLlvm>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
) {
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]);
let llmod = module.module_llvm.llmod();
@ -511,7 +511,7 @@ pub(crate) unsafe fn optimize(
_ => llvm::OptStage::PreLinkNoLTO,
};
optimize_with_new_llvm_pass_manager(cgcx, module, config, opt_level, opt_stage);
return Ok(());
return;
}
if cgcx.prof.llvm_recording_enabled() {
@ -634,7 +634,6 @@ pub(crate) unsafe fn optimize(
llvm::LLVMDisposePassManager(fpm);
llvm::LLVMDisposePassManager(mpm);
}
Ok(())
}
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {

View File

@ -2322,13 +2322,13 @@ fn set_members_of_composite_type(
DIB(cx),
composite_type_metadata,
Some(type_array),
type_params,
Some(type_params),
);
}
}
/// Computes the type parameters for a type, if any, for the given metadata.
fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'ll DIArray> {
fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> &'ll DIArray {
if let ty::Adt(def, substs) = *ty.kind() {
if substs.types().next().is_some() {
let generics = cx.tcx.generics_of(def.did);
@ -2358,10 +2358,10 @@ fn compute_type_parameters(cx: &CodegenCx<'ll, 'tcx>, ty: Ty<'tcx>) -> Option<&'
})
.collect();
return Some(create_DIArray(DIB(cx), &template_params[..]));
return create_DIArray(DIB(cx), &template_params[..]);
}
}
return Some(create_DIArray(DIB(cx), &[]));
return create_DIArray(DIB(cx), &[]);
fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
let mut names = generics

View File

@ -160,7 +160,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
module: &ModuleCodegen<Self::Module>,
config: &ModuleConfig,
) -> Result<(), FatalError> {
back::write::optimize(cgcx, diag_handler, module, config)
Ok(back::write::optimize(cgcx, diag_handler, module, config))
}
unsafe fn optimize_thin(
cgcx: &CodegenContext<Self>,

View File

@ -522,7 +522,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mut bx: Bx,
terminator: &mir::Terminator<'tcx>,
func: &mir::Operand<'tcx>,
args: &Vec<mir::Operand<'tcx>>,
args: &[mir::Operand<'tcx>],
destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>,
cleanup: Option<mir::BasicBlock>,
fn_span: Span,

View File

@ -603,7 +603,7 @@ fn handle_explain(registry: Registry, code: &str, output: ErrorOutputType) {
}
}
fn show_content_with_pager(content: &String) {
fn show_content_with_pager(content: &str) {
let pager_name = env::var_os("PAGER").unwrap_or_else(|| {
if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") }
});

View File

@ -417,7 +417,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
// obviously it never weeds out ALL errors.
fn process_errors(
&self,
errors: &Vec<RegionResolutionError<'tcx>>,
errors: &[RegionResolutionError<'tcx>],
) -> Vec<RegionResolutionError<'tcx>> {
debug!("process_errors()");
@ -442,7 +442,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
};
let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
errors.clone()
errors.to_owned()
} else {
errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
};

View File

@ -5,8 +5,8 @@ use syn::parse::{Parse, ParseStream, Result};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
use syn::{
braced, parenthesized, parse_macro_input, AttrStyle, Attribute, Block, Error, Expr, Ident,
ReturnType, Token, Type,
braced, parenthesized, parse_macro_input, parse_quote, AttrStyle, Attribute, Block, Error,
Expr, Ident, ReturnType, Token, Type,
};
mod kw {
@ -272,6 +272,40 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
if desc.is_some() {
panic!("duplicate modifier `desc` for query `{}`", query.name);
}
// If there are no doc-comments, give at least some idea of what
// it does by showing the query description.
if query.doc_comments.is_empty() {
use ::syn::*;
let mut list = list.iter();
let format_str: String = match list.next() {
Some(&Expr::Lit(ExprLit { lit: Lit::Str(ref lit_str), .. })) => {
lit_str.value().replace("`{}`", "{}") // We add them later anyways for consistency
}
_ => panic!("Expected a string literal"),
};
let mut fmt_fragments = format_str.split("{}");
let mut doc_string = fmt_fragments.next().unwrap().to_string();
list.map(::quote::ToTokens::to_token_stream).zip(fmt_fragments).for_each(
|(tts, next_fmt_fragment)| {
use ::core::fmt::Write;
write!(
&mut doc_string,
" `{}` {}",
tts.to_string().replace(" . ", "."),
next_fmt_fragment,
)
.unwrap();
},
);
let doc_string = format!(
"[query description - consider adding a doc-comment!] {}",
doc_string
);
let comment = parse_quote! {
#[doc = #doc_string]
};
query.doc_comments.push(comment);
}
desc = Some((tcx, list));
}
QueryModifier::FatalCycle => {

View File

@ -574,7 +574,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
/// format!("Expected a point greater than ({x}, {y})", x = self.x, y = self.y)
/// ```
/// This function builds the entire call to format!.
fn build_format(&self, input: &String, span: proc_macro2::Span) -> proc_macro2::TokenStream {
fn build_format(&self, input: &str, span: proc_macro2::Span) -> proc_macro2::TokenStream {
// This set is used later to generate the final format string. To keep builds reproducible,
// the iteration order needs to be deterministic, hence why we use a BTreeSet here instead
// of a HashSet.

View File

@ -954,7 +954,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&self,
def_id: DefId,
target_place: PlaceRef<'tcx>,
places: &Vec<Operand<'tcx>>,
places: &[Operand<'tcx>],
) -> Option<(Span, Option<GeneratorKind>, Span)> {
debug!(
"closure_span: def_id={:?} target_place={:?} places={:?}",

View File

@ -58,11 +58,7 @@ impl vll::LinkElem for Appearance {
}
impl LocalUseMap {
crate fn build(
live_locals: &Vec<Local>,
elements: &RegionValueElements,
body: &Body<'_>,
) -> Self {
crate fn build(live_locals: &[Local], elements: &RegionValueElements, body: &Body<'_>) -> Self {
let nones = IndexVec::from_elem_n(None, body.local_decls.len());
let mut local_use_map = LocalUseMap {
first_def_at: nones.clone(),

View File

@ -153,7 +153,7 @@ impl<T: Copy + Eq + Hash + std::fmt::Debug, PATH: Default> RefTracking<T, PATH>
}
/// Format a path
fn write_path(out: &mut String, path: &Vec<PathElem>) {
fn write_path(out: &mut String, path: &[PathElem]) {
use self::PathElem::*;
for elem in path.iter() {

View File

@ -140,7 +140,7 @@ impl<'a> BcbCounters<'a> {
/// message for subsequent debugging.
fn make_bcb_counters(
&mut self,
coverage_spans: &Vec<CoverageSpan>,
coverage_spans: &[CoverageSpan],
) -> Result<Vec<CoverageKind>, Error> {
debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
let num_bcbs = self.basic_coverage_blocks.num_nodes();
@ -465,7 +465,7 @@ impl<'a> BcbCounters<'a> {
fn choose_preferred_expression_branch(
&self,
traversal: &TraverseCoverageGraphWithLoops,
branches: &Vec<BcbBranch>,
branches: &[BcbBranch],
) -> BcbBranch {
let branch_needs_a_counter =
|branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
@ -509,7 +509,7 @@ impl<'a> BcbCounters<'a> {
fn find_some_reloop_branch(
&self,
traversal: &TraverseCoverageGraphWithLoops,
branches: &Vec<BcbBranch>,
branches: &[BcbBranch],
) -> Option<BcbBranch> {
let branch_needs_a_counter =
|branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();

View File

@ -99,7 +99,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> {
&self,
def_id: DefId,
substs_ref: SubstsRef<'tcx>,
args: &Vec<Operand<'tcx>>,
args: &[Operand<'tcx>],
source_info: SourceInfo,
) {
let param_env = self.tcx.param_env(def_id);
@ -162,7 +162,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> {
.unwrap_or(None)
}
fn nth_arg_span(&self, args: &Vec<Operand<'tcx>>, n: usize) -> Span {
fn nth_arg_span(&self, args: &[Operand<'tcx>], n: usize) -> Span {
match &args[n] {
Operand::Copy(place) | Operand::Move(place) => {
self.body.local_decls[place.local].source_info.span

View File

@ -79,7 +79,7 @@ crate struct PlaceBuilder<'tcx> {
/// part of a path that is captued by a closure. We stop applying projections once we see the first
/// projection that isn't captured by a closure.
fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
mir_projections: &Vec<PlaceElem<'tcx>>,
mir_projections: &[PlaceElem<'tcx>],
) -> Vec<HirProjectionKind> {
let mut hir_projections = Vec::new();
@ -128,7 +128,7 @@ fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
/// list are being applied to the same root variable.
fn is_ancestor_or_same_capture(
proj_possible_ancestor: &Vec<HirProjectionKind>,
proj_capture: &Vec<HirProjectionKind>,
proj_capture: &[HirProjectionKind],
) -> bool {
// We want to make sure `is_ancestor_or_same_capture("x.0.0", "x.0")` to return false.
// Therefore we can't just check if all projections are same in the zipped iterator below.
@ -171,7 +171,7 @@ fn find_capture_matching_projections<'a, 'tcx>(
typeck_results: &'a ty::TypeckResults<'tcx>,
var_hir_id: HirId,
closure_def_id: DefId,
projections: &Vec<PlaceElem<'tcx>>,
projections: &[PlaceElem<'tcx>],
) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> {
let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?;
let root_variable_min_captures = closure_min_captures.get(&var_hir_id)?;

View File

@ -721,13 +721,9 @@ impl<'a> Parser<'a> {
Ok(t) => {
// Parsed successfully, therefore most probably the code only
// misses a separator.
let mut exp_span = self.sess.source_map().next_point(sp);
if self.sess.source_map().is_multiline(exp_span) {
exp_span = sp;
}
expect_err
.span_suggestion_short(
exp_span,
sp,
&format!("missing `{}`", token_str),
token_str,
Applicability::MaybeIncorrect,

View File

@ -185,15 +185,15 @@ impl<'a> Resolver<'a> {
crate fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
match res {
Res::Def(DefKind::Macro(..), def_id) => self.get_macro_by_def_id(def_id),
Res::Def(DefKind::Macro(..), def_id) => Some(self.get_macro_by_def_id(def_id)),
Res::NonMacroAttr(attr_kind) => Some(self.non_macro_attr(attr_kind.is_used())),
_ => None,
}
}
crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Option<Lrc<SyntaxExtension>> {
crate fn get_macro_by_def_id(&mut self, def_id: DefId) -> Lrc<SyntaxExtension> {
if let Some(ext) = self.macro_map.get(&def_id) {
return Some(ext.clone());
return ext.clone();
}
let ext = Lrc::new(match self.cstore().load_macro_untracked(def_id, &self.session) {
@ -202,7 +202,7 @@ impl<'a> Resolver<'a> {
});
self.macro_map.insert(def_id, ext.clone());
Some(ext)
ext
}
crate fn build_reduced_graph(

View File

@ -1151,13 +1151,11 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
/// When evaluating a `trait` use its associated types' idents for suggestions in E0412.
fn with_trait_items<T>(
&mut self,
trait_items: &'ast Vec<P<AssocItem>>,
trait_items: &'ast [P<AssocItem>],
f: impl FnOnce(&mut Self) -> T,
) -> T {
let trait_assoc_items = replace(
&mut self.diagnostic_metadata.current_trait_assoc_items,
Some(&trait_items[..]),
);
let trait_assoc_items =
replace(&mut self.diagnostic_metadata.current_trait_assoc_items, Some(&trait_items));
let result = f(self);
self.diagnostic_metadata.current_trait_assoc_items = trait_assoc_items;
result

View File

@ -1991,14 +1991,13 @@ impl<'a> Resolver<'a> {
{
// The macro is a proc macro derive
if let Some(def_id) = module.expansion.expn_data().macro_def_id {
if let Some(ext) = self.get_macro_by_def_id(def_id) {
if !ext.is_builtin
&& ext.macro_kind() == MacroKind::Derive
&& parent.expansion.outer_expn_is_descendant_of(span.ctxt())
{
*poisoned = Some(node_id);
return module.parent;
}
let ext = self.get_macro_by_def_id(def_id);
if !ext.is_builtin
&& ext.macro_kind() == MacroKind::Derive
&& parent.expansion.outer_expn_is_descendant_of(span.ctxt())
{
*poisoned = Some(node_id);
return module.parent;
}
}
}

View File

@ -76,7 +76,7 @@ impl<'a> FileSearch<'a> {
pub fn new(
sysroot: &'a Path,
triple: &'a str,
search_paths: &'a Vec<SearchPath>,
search_paths: &'a [SearchPath],
tlib_path: &'a SearchPath,
kind: PathKind,
) -> FileSearch<'a> {

View File

@ -247,7 +247,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
self.assemble_candidates_for_trait_alias(obligation, &mut candidates)?;
self.assemble_candidates_for_trait_alias(obligation, &mut candidates);
// Other bounds. Consider both in-scope bounds from fn decl
// and applicable impls. There is a certain set of precedence rules here.
@ -259,11 +259,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// User-defined copy impls are permitted, but only for
// structs and enums.
self.assemble_candidates_from_impls(obligation, &mut candidates)?;
self.assemble_candidates_from_impls(obligation, &mut candidates);
// For other types, we'll use the builtin rules.
let copy_conditions = self.copy_clone_conditions(obligation);
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates)?;
self.assemble_builtin_bound_candidates(copy_conditions, &mut candidates);
} else if lang_items.discriminant_kind_trait() == Some(def_id) {
// `DiscriminantKind` is automatically implemented for every type.
candidates.vec.push(DiscriminantKindCandidate);
@ -271,7 +271,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Sized is never implementable by end-users, it is
// always automatically computed.
let sized_conditions = self.sized_conditions(obligation);
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates)?;
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
} else if lang_items.unsize_trait() == Some(def_id) {
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
} else {
@ -280,13 +280,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
// types have builtin support for `Clone`.
let clone_conditions = self.copy_clone_conditions(obligation);
self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates)?;
self.assemble_builtin_bound_candidates(clone_conditions, &mut candidates);
}
self.assemble_generator_candidates(obligation, &mut candidates)?;
self.assemble_closure_candidates(obligation, &mut candidates)?;
self.assemble_fn_pointer_candidates(obligation, &mut candidates)?;
self.assemble_candidates_from_impls(obligation, &mut candidates)?;
self.assemble_generator_candidates(obligation, &mut candidates);
self.assemble_closure_candidates(obligation, &mut candidates);
self.assemble_fn_pointer_candidates(obligation, &mut candidates);
self.assemble_candidates_from_impls(obligation, &mut candidates);
self.assemble_candidates_from_object_ty(obligation, &mut candidates);
}
@ -295,7 +295,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Auto implementations have lower priority, so we only
// consider triggering a default if there is no other impl that can apply.
if candidates.vec.is_empty() {
self.assemble_candidates_from_auto_impls(obligation, &mut candidates)?;
self.assemble_candidates_from_auto_impls(obligation, &mut candidates);
}
debug!("candidate list size: {}", candidates.vec.len());
Ok(candidates)
@ -367,9 +367,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
) {
if self.tcx().lang_items().gen_trait() != Some(obligation.predicate.def_id()) {
return Ok(());
return;
}
// Okay to skip binder because the substs on generator types never
@ -388,8 +388,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
_ => {}
}
Ok(())
}
/// Checks for the artificial impl that the compiler will create for an obligation like `X :
@ -402,11 +400,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
) {
let kind = match self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) {
Some(k) => k,
None => {
return Ok(());
return;
}
};
@ -435,8 +433,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
_ => {}
}
Ok(())
}
/// Implements one of the `Fn()` family for a fn pointer.
@ -444,10 +440,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
) {
// We provide impl of all fn traits for fn pointers.
if self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()).is_none() {
return Ok(());
return;
}
// Okay to skip binder because what we are inspecting doesn't involve bound regions.
@ -485,8 +481,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
_ => {}
}
Ok(())
}
/// Searches for impls that might apply to `obligation`.
@ -494,7 +488,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
) {
debug!(?obligation, "assemble_candidates_from_impls");
// Essentially any user-written impl will match with an error type,
@ -504,7 +498,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// Since compilation is already guaranteed to fail, this is just
// to try to show the 'nicest' possible errors to the user.
if obligation.references_error() {
return Ok(());
return;
}
self.tcx().for_each_relevant_impl(
@ -518,15 +512,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
});
},
);
Ok(())
}
fn assemble_candidates_from_auto_impls(
&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
) {
// Okay to skip binder here because the tests we do below do not involve bound regions.
let self_ty = obligation.self_ty().skip_binder();
debug!(?self_ty, "assemble_candidates_from_auto_impls");
@ -585,8 +577,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
_ => candidates.vec.push(AutoImplCandidate(def_id)),
}
}
Ok(())
}
/// Searches for impls that might apply to `obligation`.
@ -753,7 +743,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
obligation: &TraitObligation<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
) {
// Okay to skip binder here because the tests we do below do not involve bound regions.
let self_ty = obligation.self_ty().skip_binder();
debug!(?self_ty, "assemble_candidates_for_trait_alias");
@ -763,8 +753,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
if self.tcx().is_trait_alias(def_id) {
candidates.vec.push(TraitAliasCandidate(def_id));
}
Ok(())
}
/// Assembles the trait which are built-in to the language itself:
@ -773,7 +761,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
&mut self,
conditions: BuiltinImplConditions<'tcx>,
candidates: &mut SelectionCandidateSet<'tcx>,
) -> Result<(), SelectionError<'tcx>> {
) {
match conditions {
BuiltinImplConditions::Where(nested) => {
debug!(?nested, "builtin_bound");
@ -787,7 +775,5 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
candidates.ambiguous = true;
}
}
Ok(())
}
}

View File

@ -267,15 +267,13 @@ crate fn check_drop_obligations<'a, 'tcx>(
ty: Ty<'tcx>,
span: Span,
body_id: hir::HirId,
) -> Result<(), ErrorReported> {
) {
debug!("check_drop_obligations typ: {:?}", ty);
let cause = &ObligationCause::misc(span, body_id);
let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty);
debug!("dropck_outlives = {:#?}", infer_ok);
rcx.fcx.register_infer_ok_obligations(infer_ok);
Ok(())
}
// This is an implementation of the TypeRelation trait with the

View File

@ -423,9 +423,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
probe_cx.assemble_inherent_candidates();
match scope {
ProbeScope::TraitsInScope => {
probe_cx.assemble_extension_candidates_for_traits_in_scope(scope_expr_id)?
probe_cx.assemble_extension_candidates_for_traits_in_scope(scope_expr_id)
}
ProbeScope::AllTraits => probe_cx.assemble_extension_candidates_for_all_traits()?,
ProbeScope::AllTraits => probe_cx.assemble_extension_candidates_for_all_traits(),
};
op(probe_cx)
})
@ -866,35 +866,29 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
}
}
fn assemble_extension_candidates_for_traits_in_scope(
&mut self,
expr_hir_id: hir::HirId,
) -> Result<(), MethodError<'tcx>> {
fn assemble_extension_candidates_for_traits_in_scope(&mut self, expr_hir_id: hir::HirId) {
let mut duplicates = FxHashSet::default();
let opt_applicable_traits = self.tcx.in_scope_traits(expr_hir_id);
if let Some(applicable_traits) = opt_applicable_traits {
for trait_candidate in applicable_traits.iter() {
let trait_did = trait_candidate.def_id;
if duplicates.insert(trait_did) {
let result = self.assemble_extension_candidates_for_trait(
self.assemble_extension_candidates_for_trait(
&trait_candidate.import_ids,
trait_did,
);
result?;
}
}
}
Ok(())
}
fn assemble_extension_candidates_for_all_traits(&mut self) -> Result<(), MethodError<'tcx>> {
fn assemble_extension_candidates_for_all_traits(&mut self) {
let mut duplicates = FxHashSet::default();
for trait_info in suggest::all_traits(self.tcx) {
if duplicates.insert(trait_info.def_id) {
self.assemble_extension_candidates_for_trait(&smallvec![], trait_info.def_id)?;
self.assemble_extension_candidates_for_trait(&smallvec![], trait_info.def_id);
}
}
Ok(())
}
pub fn matches_return_type(
@ -932,7 +926,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
&mut self,
import_ids: &SmallVec<[LocalDefId; 1]>,
trait_def_id: DefId,
) -> Result<(), MethodError<'tcx>> {
) {
debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id);
let trait_substs = self.fresh_item_substs(trait_def_id);
let trait_ref = ty::TraitRef::new(trait_def_id, trait_substs);
@ -980,7 +974,6 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
);
}
}
Ok(())
}
fn candidate_method_names(&self) -> Vec<Ident> {
@ -1027,7 +1020,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
let span = self.span;
let tcx = self.tcx;
self.assemble_extension_candidates_for_all_traits()?;
self.assemble_extension_candidates_for_all_traits();
let out_of_scope_traits = match self.pick_core() {
Some(Ok(p)) => vec![p.item.container.id()],

View File

@ -325,7 +325,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
pat.each_binding(|_, hir_id, span, _| {
let typ = self.resolve_node_type(hir_id);
let body_id = self.body_id;
let _ = dropck::check_drop_obligations(self, typ, span, body_id);
dropck::check_drop_obligations(self, typ, span, body_id);
})
}
}
@ -488,7 +488,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
if place_with_id.place.projections.is_empty() {
let typ = self.resolve_type(place_with_id.place.ty());
let body_id = self.body_id;
let _ = dropck::check_drop_obligations(self, typ, span, body_id);
dropck::check_drop_obligations(self, typ, span, body_id);
}
}
}

View File

@ -14,11 +14,13 @@
#![feature(core_intrinsics)]
#![feature(nll)]
#![feature(panic_runtime)]
#![feature(std_internals)]
#![feature(staged_api)]
#![feature(rustc_attrs)]
#![feature(asm)]
use core::any::Any;
use core::panic::BoxMeUp;
#[rustc_std_internal_symbol]
#[allow(improper_ctypes_definitions)]
@ -28,7 +30,7 @@ pub unsafe extern "C" fn __rust_panic_cleanup(_: *mut u8) -> *mut (dyn Any + Sen
// "Leak" the payload and shim to the relevant abort on the platform in question.
#[rustc_std_internal_symbol]
pub unsafe extern "C" fn __rust_start_panic(_payload: usize) -> u32 {
pub unsafe extern "C" fn __rust_start_panic(_payload: *mut &mut dyn BoxMeUp) -> u32 {
abort();
cfg_if::cfg_if! {

View File

@ -104,9 +104,8 @@ pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any
// implementation.
#[rustc_std_internal_symbol]
#[unwind(allowed)]
pub unsafe extern "C" fn __rust_start_panic(payload: usize) -> u32 {
let payload = payload as *mut &mut dyn BoxMeUp;
let payload = (*payload).take_box();
pub unsafe extern "C" fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32 {
let payload = Box::from_raw((*payload).take_box());
imp::panic(Box::from_raw(payload))
imp::panic(payload)
}

View File

@ -44,11 +44,11 @@ use realstd::io::set_output_capture;
extern "C" {
fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static);
/// `payload` is actually a `*mut &mut dyn BoxMeUp` but that would cause FFI warnings.
/// It cannot be `Box<dyn BoxMeUp>` because the other end of this call does not depend
/// on liballoc, and thus cannot use `Box`.
/// `payload` is passed through another layer of raw pointers as `&mut dyn Trait` is not
/// FFI-safe. `BoxMeUp` lazily performs allocation only when needed (this avoids allocations
/// when using the "abort" panic runtime).
#[unwind(allowed)]
fn __rust_start_panic(payload: usize) -> u32;
fn __rust_start_panic(payload: *mut &mut dyn BoxMeUp) -> u32;
}
/// This function is called by the panic runtime if FFI code catches a Rust
@ -637,7 +637,7 @@ pub fn rust_panic_without_hook(payload: Box<dyn Any + Send>) -> ! {
fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! {
let code = unsafe {
let obj = &mut msg as *mut &mut dyn BoxMeUp;
__rust_start_panic(obj as usize)
__rust_start_panic(obj)
};
rtabort!("failed to initiate panic, error {}", code)
}

View File

@ -4,17 +4,21 @@
<DisplayString>{data_ptr,[length]s8}</DisplayString>
<StringView>data_ptr,[length]s8</StringView>
<Expand>
<Item Name="[size]" ExcludeView="simple">length</Item>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>
</ArrayItems>
<Item Name="[len]" ExcludeView="simple">length</Item>
<Synthetic Name="[chars]">
<Expand>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
</Expand>
</Type>
<Type Name="slice&lt;*&gt;">
<DisplayString>{{ length={length} }}</DisplayString>
<DisplayString>{{ len={length} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">length</Item>
<Item Name="[len]" ExcludeView="simple">length</Item>
<ArrayItems>
<Size>length</Size>
<ValuePointer>data_ptr</ValuePointer>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
<Type Name="alloc::vec::Vec&lt;*&gt;">
<DisplayString>{{ size={len} }}</DisplayString>
<DisplayString>{{ len={len} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">len</Item>
<Item Name="[len]" ExcludeView="simple">len</Item>
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
<ArrayItems>
<Size>len</Size>
@ -12,9 +12,9 @@
</Expand>
</Type>
<Type Name="alloc::collections::vec_deque::VecDeque&lt;*&gt;">
<DisplayString>{{ size={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
<DisplayString>{{ len={tail &lt;= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
<Item Name="[len]" ExcludeView="simple">tail &lt;= head ? head - tail : buf.cap - tail + head</Item>
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
<CustomListItems>
<Variable Name="i" InitialValue="tail" />
@ -31,7 +31,7 @@
</Expand>
</Type>
<Type Name="alloc::collections::linked_list::LinkedList&lt;*&gt;">
<DisplayString>{{ size={len} }}</DisplayString>
<DisplayString>{{ len={len} }}</DisplayString>
<Expand>
<LinkedListItems>
<Size>len</Size>
@ -42,15 +42,37 @@
</Expand>
</Type>
<Type Name="alloc::string::String">
<DisplayString>{*(char**)this,[vec.len]s8}</DisplayString>
<StringView>*(char**)this,[vec.len]s8</StringView>
<DisplayString>{(char*)vec.buf.ptr.pointer,[vec.len]s8}</DisplayString>
<StringView>(char*)vec.buf.ptr.pointer,[vec.len]s8</StringView>
<Expand>
<Item Name="[size]" ExcludeView="simple">vec.len</Item>
<Item Name="[len]" ExcludeView="simple">vec.len</Item>
<Item Name="[capacity]" ExcludeView="simple">vec.buf.cap</Item>
<ArrayItems>
<Size>vec.len</Size>
<ValuePointer>*(char**)this</ValuePointer>
</ArrayItems>
<Synthetic Name="[chars]">
<Expand>
<ArrayItems>
<Size>vec.len</Size>
<ValuePointer>(char*)vec.buf.ptr.pointer</ValuePointer>
</ArrayItems>
</Expand>
</Synthetic>
</Expand>
</Type>
<Type Name="alloc::rc::Rc&lt;*&gt;">
<DisplayString>{ptr.pointer->value}</DisplayString>
<Expand>
<ExpandedItem>ptr.pointer->value</ExpandedItem>
</Expand>
</Type>
<Type Name="alloc::sync::Arc&lt;*&gt;">
<DisplayString>{ptr.pointer->data}</DisplayString>
<Expand>
<ExpandedItem>ptr.pointer->data</ExpandedItem>
</Expand>
</Type>
<Type Name="alloc::sync::Weak&lt;*&gt;">
<DisplayString>{ptr.pointer->data}</DisplayString>
<Expand>
<ExpandedItem>ptr.pointer->data</ExpandedItem>
</Expand>
</Type>
</AutoVisualizer>

View File

@ -6,34 +6,28 @@
<Item Name="[ptr]">pointer</Item>
</Expand>
</Type>
<Type Name="core::ptr::Shared&lt;*&gt;">
<DisplayString>{{ Shared {pointer} }}</DisplayString>
<Expand>
<Item Name="[ptr]">pointer</Item>
</Expand>
</Type>
<Type Name="core::option::Option&lt;*&gt;">
<DisplayString Condition="RUST$ENUM$DISR == 0x0">{{ None }}</DisplayString>
<DisplayString Condition="RUST$ENUM$DISR == 0x1">{{ Some {__0} }}</DisplayString>
<DisplayString Condition="RUST$ENUM$DISR == 0x0">None</DisplayString>
<DisplayString Condition="RUST$ENUM$DISR == 0x1">Some({__0})</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">(ULONG)(RUST$ENUM$DISR != 0)</Item>
<Item Name="[value]" ExcludeView="simple">__0</Item>
<ArrayItems>
<Size>(ULONG)(RUST$ENUM$DISR != 0)</Size>
<ValuePointer>&amp;__0</ValuePointer>
</ArrayItems>
<Item Name="[value]" ExcludeView="simple" Condition="RUST$ENUM$DISR == 1">__0</Item>
</Expand>
</Type>
<Type Name="core::option::Option&lt;*&gt;" Priority="MediumLow">
<DisplayString Condition="*(PVOID *)this == nullptr">{{ None }}</DisplayString>
<DisplayString>{{ Some {($T1 *)this} }}</DisplayString>
<DisplayString Condition="*(void**)this == nullptr">None</DisplayString>
<DisplayString>Some({($T1 *)this})</DisplayString>
<Expand>
<Item Name="[size]" ExcludeView="simple">(ULONG)(*(PVOID *)this != nullptr)</Item>
<Item Name="[value]" ExcludeView="simple" Condition="*(PVOID *)this != nullptr">($T1 *)this</Item>
<ArrayItems>
<Size>(ULONG)(*(PVOID *)this != nullptr)</Size>
<ValuePointer>($T1 *)this</ValuePointer>
</ArrayItems>
<Item Name="Some" ExcludeView="simple" Condition="*(void**)this != nullptr">($T1 *)this</Item>
</Expand>
</Type>
</AutoVisualizer>

View File

@ -26,9 +26,9 @@
-->
<Type Name="std::collections::hash::map::HashMap&lt;*,*,*&gt;">
<DisplayString>{{ size={base.table.items} }}</DisplayString>
<DisplayString>{{ len={base.table.items} }}</DisplayString>
<Expand>
<Item Name="[size]">base.table.items</Item>
<Item Name="[len]">base.table.items</Item>
<Item Name="[capacity]">base.table.items + base.table.growth_left</Item>
<Item Name="[state]">base.hash_builder</Item>
@ -50,9 +50,9 @@
</Type>
<Type Name="std::collections::hash::set::HashSet&lt;*,*&gt;">
<DisplayString>{{ size={base.map.table.items} }}</DisplayString>
<DisplayString>{{ len={base.map.table.items} }}</DisplayString>
<Expand>
<Item Name="[size]">base.map.table.items</Item>
<Item Name="[len]">base.map.table.items</Item>
<Item Name="[capacity]">base.map.table.items + base.map.table.growth_left</Item>
<Item Name="[state]">base.map.hash_builder</Item>

View File

@ -3,12 +3,12 @@ use crate::clean::*;
crate struct StripItem(pub Item);
impl StripItem {
crate fn strip(self) -> Option<Item> {
crate fn strip(self) -> Item {
match self.0 {
Item { kind: box StrippedItem(..), .. } => Some(self.0),
Item { kind: box StrippedItem(..), .. } => self.0,
mut i => {
i.kind = box StrippedItem(i.kind);
Some(i)
i
}
}
}

View File

@ -418,7 +418,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
struct HeadingLinks<'a, 'b, 'ids, I> {
inner: I,
toc: Option<&'b mut TocBuilder>,
buf: VecDeque<(Event<'a>, Range<usize>)>,
buf: VecDeque<Event<'a>>,
id_map: &'ids mut IdMap,
}
@ -428,10 +428,8 @@ impl<'a, 'b, 'ids, I> HeadingLinks<'a, 'b, 'ids, I> {
}
}
impl<'a, 'b, 'ids, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator
for HeadingLinks<'a, 'b, 'ids, I>
{
type Item = (Event<'a>, Range<usize>);
impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a, 'b, 'ids, I> {
type Item = Event<'a>;
fn next(&mut self) -> Option<Self::Item> {
if let Some(e) = self.buf.pop_front() {
@ -439,29 +437,31 @@ impl<'a, 'b, 'ids, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator
}
let event = self.inner.next();
if let Some((Event::Start(Tag::Heading(level)), _)) = event {
if let Some(Event::Start(Tag::Heading(level))) = event {
let mut id = String::new();
for event in &mut self.inner {
match &event.0 {
match &event {
Event::End(Tag::Heading(..)) => break,
Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {}
Event::Text(text) | Event::Code(text) => {
id.extend(text.chars().filter_map(slugify));
self.buf.push_back(event);
}
_ => self.buf.push_back(event),
_ => {}
}
match event {
Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {}
event => self.buf.push_back(event),
}
}
let id = self.id_map.derive(id);
if let Some(ref mut builder) = self.toc {
let mut html_header = String::new();
html::push_html(&mut html_header, self.buf.iter().map(|(ev, _)| ev.clone()));
html::push_html(&mut html_header, self.buf.iter().cloned());
let sec = builder.push(level as u32, html_header, id.clone());
self.buf.push_front((Event::Html(format!("{} ", sec).into()), 0..0));
self.buf.push_front(Event::Html(format!("{} ", sec).into()));
}
self.buf.push_back((Event::Html(format!("</a></h{}>", level).into()), 0..0));
self.buf.push_back(Event::Html(format!("</a></h{}>", level).into()));
let start_tags = format!(
"<h{level} id=\"{id}\" class=\"section-header\">\
@ -469,7 +469,7 @@ impl<'a, 'b, 'ids, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator
id = id,
level = level
);
return Some((Event::Html(start_tags.into()), 0..0));
return Some(Event::Html(start_tags.into()));
}
event
}
@ -560,23 +560,23 @@ impl<'a, I> Footnotes<'a, I> {
}
}
impl<'a, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator for Footnotes<'a, I> {
type Item = (Event<'a>, Range<usize>);
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
type Item = Event<'a>;
fn next(&mut self) -> Option<Self::Item> {
loop {
match self.inner.next() {
Some((Event::FootnoteReference(ref reference), range)) => {
Some(Event::FootnoteReference(ref reference)) => {
let entry = self.get_entry(&reference);
let reference = format!(
"<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>",
(*entry).1
);
return Some((Event::Html(reference.into()), range));
return Some(Event::Html(reference.into()));
}
Some((Event::Start(Tag::FootnoteDefinition(def)), _)) => {
Some(Event::Start(Tag::FootnoteDefinition(def))) => {
let mut content = Vec::new();
for (event, _) in &mut self.inner {
for event in &mut self.inner {
if let Event::End(Tag::FootnoteDefinition(..)) = event {
break;
}
@ -607,7 +607,7 @@ impl<'a, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator for Footnotes<'
ret.push_str("</li>");
}
ret.push_str("</ol></div>");
return Some((Event::Html(ret.into()), 0..0));
return Some(Event::Html(ret.into()));
} else {
return None;
}
@ -917,14 +917,13 @@ impl Markdown<'_> {
};
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
let p = p.into_offset_iter();
let mut s = String::with_capacity(md.len() * 3 / 2);
let p = HeadingLinks::new(p, None, &mut ids);
let p = Footnotes::new(p);
let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
let p = LinkReplacer::new(p, links);
let p = CodeBlocks::new(p, codes, edition, playground);
let p = Footnotes::new(p);
html::push_html(&mut s, p);
s
@ -935,7 +934,7 @@ impl MarkdownWithToc<'_> {
crate fn into_string(self) -> String {
let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
let p = Parser::new_ext(md, opts()).into_offset_iter();
let p = Parser::new_ext(md, opts());
let mut s = String::with_capacity(md.len() * 3 / 2);
@ -943,8 +942,8 @@ impl MarkdownWithToc<'_> {
{
let p = HeadingLinks::new(p, Some(&mut toc), &mut ids);
let p = CodeBlocks::new(p, codes, edition, playground);
let p = Footnotes::new(p);
let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
html::push_html(&mut s, p);
}
@ -960,19 +959,19 @@ impl MarkdownHtml<'_> {
if md.is_empty() {
return String::new();
}
let p = Parser::new_ext(md, opts()).into_offset_iter();
let p = Parser::new_ext(md, opts());
// Treat inline HTML as plain text.
let p = p.map(|event| match event.0 {
Event::Html(text) => (Event::Text(text), event.1),
let p = p.map(|event| match event {
Event::Html(text) => Event::Text(text),
_ => event,
});
let mut s = String::with_capacity(md.len() * 3 / 2);
let p = HeadingLinks::new(p, None, &mut ids);
let p = CodeBlocks::new(p, codes, edition, playground);
let p = Footnotes::new(p);
let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
html::push_html(&mut s, p);
s
@ -1125,45 +1124,50 @@ crate fn plain_text_summary(md: &str) -> String {
s
}
crate fn markdown_links(md: &str) -> Vec<(String, Range<usize>)> {
crate fn markdown_links(md: &str) -> Vec<(String, Option<Range<usize>>)> {
if md.is_empty() {
return vec![];
}
let mut links = vec![];
// Used to avoid mutable borrow issues in the `push` closure
// Probably it would be more efficient to use a `RefCell` but it doesn't seem worth the churn.
let mut shortcut_links = vec![];
let span_for_link = |link: &str, span: Range<usize>| {
// Pulldown includes the `[]` as well as the URL. Only highlight the relevant span.
// NOTE: uses `rfind` in case the title and url are the same: `[Ok][Ok]`
match md[span.clone()].rfind(link) {
Some(start) => {
let start = span.start + start;
start..start + link.len()
{
let locate = |s: &str| unsafe {
let s_start = s.as_ptr();
let s_end = s_start.add(s.len());
let md_start = md.as_ptr();
let md_end = md_start.add(md.len());
if md_start <= s_start && s_end <= md_end {
let start = s_start.offset_from(md_start) as usize;
let end = s_end.offset_from(md_start) as usize;
Some(start..end)
} else {
None
}
// This can happen for things other than intra-doc links, like `#1` expanded to `https://github.com/rust-lang/rust/issues/1`.
None => span,
}
};
let mut push = |link: BrokenLink<'_>| {
let span = span_for_link(link.reference, link.span);
shortcut_links.push((link.reference.to_owned(), span));
None
};
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push));
};
// There's no need to thread an IdMap through to here because
// the IDs generated aren't going to be emitted anywhere.
let mut ids = IdMap::new();
let iter = Footnotes::new(HeadingLinks::new(p.into_offset_iter(), None, &mut ids));
let mut push = |link: BrokenLink<'_>| {
// FIXME: use `link.span` instead of `locate`
// (doing it now includes the `[]` as well as the text)
shortcut_links.push((link.reference.to_owned(), locate(link.reference)));
None
};
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut push));
for ev in iter {
if let Event::Start(Tag::Link(_, dest, _)) = ev.0 {
debug!("found link: {}", dest);
let span = span_for_link(&dest, ev.1);
links.push((dest.into_string(), span));
// There's no need to thread an IdMap through to here because
// the IDs generated aren't going to be emitted anywhere.
let mut ids = IdMap::new();
let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids));
for ev in iter {
if let Event::Start(Tag::Link(_, dest, _)) = ev {
debug!("found link: {}", dest);
links.push(match dest {
CowStr::Borrowed(s) => (s.to_owned(), locate(s)),
s @ (CowStr::Boxed(..) | CowStr::Inlined(..)) => (s.into_string(), None),
});
}
}
}

View File

@ -3483,7 +3483,7 @@ enum AssocItemLink<'a> {
}
impl<'a> AssocItemLink<'a> {
fn anchor(&self, id: &'a String) -> Self {
fn anchor(&self, id: &'a str) -> Self {
match *self {
AssocItemLink::Anchor(_) => AssocItemLink::Anchor(Some(&id)),
ref other => *other,

View File

@ -245,7 +245,7 @@ struct DiagnosticInfo<'a> {
item: &'a Item,
dox: &'a str,
ori_link: &'a str,
link_range: Range<usize>,
link_range: Option<Range<usize>>,
}
#[derive(Clone, Debug, Hash)]
@ -982,7 +982,7 @@ impl LinkCollector<'_, '_> {
parent_node: Option<DefId>,
krate: CrateNum,
ori_link: String,
link_range: Range<usize>,
link_range: Option<Range<usize>>,
) -> Option<ItemLink> {
trace!("considering link '{}'", ori_link);
@ -1628,7 +1628,7 @@ fn report_diagnostic(
msg: &str,
item: &Item,
dox: &str,
link_range: &Range<usize>,
link_range: &Option<Range<usize>>,
decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
) {
let hir_id = match cx.as_local_hir_id(item.def_id) {
@ -1646,26 +1646,31 @@ fn report_diagnostic(
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
let mut diag = lint.build(msg);
let span = super::source_span_for_markdown_range(cx, dox, link_range, attrs);
if let Some(sp) = span {
diag.set_span(sp);
} else {
// blah blah blah\nblah\nblah [blah] blah blah\nblah blah
// ^ ~~~~
// | link_range
// last_new_line_offset
let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
let span = link_range
.as_ref()
.and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs));
// Print the line containing the `link_range` and manually mark it with '^'s.
diag.note(&format!(
"the link appears in this line:\n\n{line}\n\
{indicator: <before$}{indicator:^<found$}",
line = line,
indicator = "",
before = link_range.start - last_new_line_offset,
found = link_range.len(),
));
if let Some(link_range) = link_range {
if let Some(sp) = span {
diag.set_span(sp);
} else {
// blah blah blah\nblah\nblah [blah] blah blah\nblah blah
// ^ ~~~~
// | link_range
// last_new_line_offset
let last_new_line_offset = dox[..link_range.start].rfind('\n').map_or(0, |n| n + 1);
let line = dox[last_new_line_offset..].lines().next().unwrap_or("");
// Print the line containing the `link_range` and manually mark it with '^'s.
diag.note(&format!(
"the link appears in this line:\n\n{line}\n\
{indicator: <before$}{indicator:^<found$}",
line = line,
indicator = "",
before = link_range.start - last_new_line_offset,
found = link_range.len(),
));
}
}
decorate(&mut diag, span);
@ -1685,7 +1690,7 @@ fn resolution_failure(
path_str: &str,
disambiguator: Option<Disambiguator>,
dox: &str,
link_range: Range<usize>,
link_range: Option<Range<usize>>,
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
) {
let tcx = collector.cx.tcx;
@ -1909,7 +1914,7 @@ fn anchor_failure(
item: &Item,
path_str: &str,
dox: &str,
link_range: Range<usize>,
link_range: Option<Range<usize>>,
failure: AnchorFailure,
) {
let msg = match failure {
@ -1934,7 +1939,7 @@ fn ambiguity_error(
item: &Item,
path_str: &str,
dox: &str,
link_range: Range<usize>,
link_range: Option<Range<usize>>,
candidates: Vec<Res>,
) {
let mut msg = format!("`{}` is ", path_str);
@ -1983,12 +1988,13 @@ fn suggest_disambiguator(
path_str: &str,
dox: &str,
sp: Option<rustc_span::Span>,
link_range: &Range<usize>,
link_range: &Option<Range<usize>>,
) {
let suggestion = disambiguator.suggestion();
let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
if let Some(sp) = sp {
let link_range = link_range.as_ref().expect("must have a link range if we have a span");
let msg = if dox.bytes().nth(link_range.start) == Some(b'`') {
format!("`{}`", suggestion.as_help(path_str))
} else {
@ -2007,7 +2013,7 @@ fn privacy_error(
item: &Item,
path_str: &str,
dox: &str,
link_range: Range<usize>,
link_range: Option<Range<usize>>,
) {
let sym;
let item_name = match item.name {

View File

@ -49,7 +49,7 @@ impl<'a> DocFolder for Stripper<'a> {
let old = mem::replace(&mut self.update_retained, false);
let ret = StripItem(self.fold_item_recur(i)).strip();
self.update_retained = old;
return ret;
return Some(ret);
}
_ => return None,
}

View File

@ -51,7 +51,7 @@ impl<'a> DocFolder for Stripper<'a> {
clean::StructFieldItem(..) => {
if !i.visibility.is_public() {
return StripItem(i).strip();
return Some(StripItem(i).strip());
}
}
@ -61,7 +61,7 @@ impl<'a> DocFolder for Stripper<'a> {
let old = mem::replace(&mut self.update_retained, false);
let ret = StripItem(self.fold_item_recur(i)).strip();
self.update_retained = old;
return ret;
return Some(ret);
}
}

View File

@ -10,8 +10,8 @@
// cdb-command: g
// cdb-command: dx hash_set,d
// cdb-check:hash_set,d [...] : { size=15 } [Type: [...]::HashSet<u64, [...]>]
// cdb-check: [size] : 15 [Type: [...]]
// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64, [...]>]
// cdb-check: [len] : 15 [Type: [...]]
// cdb-check: [capacity] : [...]
// cdb-check: [[...]] [...] : 0 [Type: u64]
// cdb-command: dx hash_set,d
@ -44,8 +44,8 @@
// cdb-check: [[...]] [...] : 14 [Type: u64]
// cdb-command: dx hash_map,d
// cdb-check:hash_map,d [...] : { size=15 } [Type: [...]::HashMap<u64, u64, [...]>]
// cdb-check: [size] : 15 [Type: [...]]
// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64, u64, [...]>]
// cdb-check: [len] : 15 [Type: [...]]
// cdb-check: [capacity] : [...]
// cdb-check: ["0x0"] : 0 [Type: unsigned __int64]
// cdb-command: dx hash_map,d

View File

@ -74,8 +74,8 @@
// NOTE: While slices have a .natvis entry that works in VS & VS Code, it fails in CDB 10.0.18362.1
// cdb-command: dx vec,d
// cdb-check:vec,d [...] : { size=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
// cdb-check: [size] : 4 [Type: [...]]
// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
// cdb-check: [len] : 4 [Type: [...]]
// cdb-check: [capacity] : [...] [Type: [...]]
// cdb-check: [0] : 4 [Type: unsigned __int64]
// cdb-check: [1] : 5 [Type: unsigned __int64]
@ -89,8 +89,10 @@
// cdb-command: dx string
// cdb-check:string : "IAMA string!" [Type: [...]::String]
// cdb-check: [<Raw View>] [Type: [...]::String]
// cdb-check: [size] : 0xc [Type: [...]]
// cdb-check: [len] : 0xc [Type: [...]]
// cdb-check: [capacity] : 0xc [Type: [...]]
// cdb-command: dx -r2 string
// cdb-check: [0] : 73 'I' [Type: char]
// cdb-check: [1] : 65 'A' [Type: char]
// cdb-check: [2] : 77 'M' [Type: char]
@ -109,11 +111,11 @@
// NOTE: OsString doesn't have a .natvis entry yet.
// cdb-command: dx some
// cdb-check:some : { Some 8 } [Type: [...]::Option<i16>]
// cdb-check:some : Some(8) [Type: [...]::Option<i16>]
// cdb-command: dx none
// cdb-check:none : { None } [Type: [...]::Option<i64>]
// cdb-check:none : None [Type: [...]::Option<i64>]
// cdb-command: dx some_string
// cdb-check:some_string : { Some "IAMA optional string!" } [[...]::Option<[...]::String>]
// cdb-check:some_string : Some("IAMA optional string!") [[...]::Option<[...]::String>]
#![allow(unused_variables)]
use std::ffi::OsString;

View File

@ -0,0 +1,7 @@
// Test that errors point to the reference, not to the title text.
#![deny(broken_intra_doc_links)]
//! Links to [a] [link][a]
//!
//! [a]: std::process::Comman
//~^ ERROR unresolved
//~| ERROR unresolved

View File

@ -0,0 +1,20 @@
error: unresolved link to `std::process::Comman`
--> $DIR/reference-links.rs:5:10
|
LL | //! [a]: std::process::Comman
| ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
|
note: the lint level is defined here
--> $DIR/reference-links.rs:2:9
|
LL | #![deny(broken_intra_doc_links)]
| ^^^^^^^^^^^^^^^^^^^^^^
error: unresolved link to `std::process::Comman`
--> $DIR/reference-links.rs:5:10
|
LL | //! [a]: std::process::Comman
| ^^^^^^^^^^^^^^^^^^^^ no item named `Comman` in module `process`
error: aborting due to 2 previous errors

View File

@ -0,0 +1,12 @@
// Regression test for #80134.
fn main() {
(()é);
//~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator
//~| ERROR: cannot find value `é` in this scope
//~| ERROR: non-ascii idents are not fully supported
(());
//~^ ERROR: expected one of `)`, `,`, `.`, `?`, or an operator
//~| ERROR: cannot find value `氷` in this scope
//~| ERROR: non-ascii idents are not fully supported
}

View File

@ -0,0 +1,52 @@
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `é`
--> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
|
LL | (()é);
| ^
| |
| expected one of `)`, `,`, `.`, `?`, or an operator
| help: missing `,`
error: expected one of `)`, `,`, `.`, `?`, or an operator, found `氷`
--> $DIR/multibyte-char-use-seperator-issue-80134.rs:8:8
|
LL | (()氷);
| -^
| |
| expected one of `)`, `,`, `.`, `?`, or an operator
| help: missing `,`
error[E0425]: cannot find value `é` in this scope
--> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
|
LL | (()é);
| ^ not found in this scope
error[E0425]: cannot find value `氷` in this scope
--> $DIR/multibyte-char-use-seperator-issue-80134.rs:8:8
|
LL | (()氷);
| ^^ not found in this scope
error[E0658]: non-ascii idents are not fully supported
--> $DIR/multibyte-char-use-seperator-issue-80134.rs:4:8
|
LL | (()é);
| ^
|
= note: see issue #55467 <https://github.com/rust-lang/rust/issues/55467> for more information
= help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable
error[E0658]: non-ascii idents are not fully supported
--> $DIR/multibyte-char-use-seperator-issue-80134.rs:8:8
|
LL | (()氷);
| ^^
|
= note: see issue #55467 <https://github.com/rust-lang/rust/issues/55467> for more information
= help: add `#![feature(non_ascii_idents)]` to the crate attributes to enable
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0425, E0658.
For more information about an error, try `rustc --explain E0425`.

View File

@ -1,13 +0,0 @@
// run-rustfix
#![allow(unused_imports)]
pub mod x {
pub struct A;
pub struct B;
}
// `.` is similar to `,` so list parsing should continue to closing `}`
use x::{A, B}; //~ ERROR expected one of `,`, `::`, `as`, or `}`, found `.`
fn main() {}

View File

@ -1,5 +1,3 @@
// run-rustfix
#![allow(unused_imports)]
pub mod x {

View File

@ -1,5 +1,5 @@
error: expected one of `,`, `::`, `as`, or `}`, found `.`
--> $DIR/similar-tokens.rs:11:10
--> $DIR/similar-tokens.rs:9:10
|
LL | use x::{A. B};
| ^