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:
commit
507bff92fa
45 changed files with 384 additions and 276 deletions
|
@ -485,7 +485,7 @@ pub(crate) unsafe fn optimize(
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
module: &ModuleCodegen<ModuleLlvm>,
|
module: &ModuleCodegen<ModuleLlvm>,
|
||||||
config: &ModuleConfig,
|
config: &ModuleConfig,
|
||||||
) -> Result<(), FatalError> {
|
) {
|
||||||
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]);
|
let _timer = cgcx.prof.generic_activity_with_arg("LLVM_module_optimize", &module.name[..]);
|
||||||
|
|
||||||
let llmod = module.module_llvm.llmod();
|
let llmod = module.module_llvm.llmod();
|
||||||
|
@ -511,7 +511,7 @@ pub(crate) unsafe fn optimize(
|
||||||
_ => llvm::OptStage::PreLinkNoLTO,
|
_ => llvm::OptStage::PreLinkNoLTO,
|
||||||
};
|
};
|
||||||
optimize_with_new_llvm_pass_manager(cgcx, module, config, opt_level, opt_stage);
|
optimize_with_new_llvm_pass_manager(cgcx, module, config, opt_level, opt_stage);
|
||||||
return Ok(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if cgcx.prof.llvm_recording_enabled() {
|
if cgcx.prof.llvm_recording_enabled() {
|
||||||
|
@ -634,7 +634,6 @@ pub(crate) unsafe fn optimize(
|
||||||
llvm::LLVMDisposePassManager(fpm);
|
llvm::LLVMDisposePassManager(fpm);
|
||||||
llvm::LLVMDisposePassManager(mpm);
|
llvm::LLVMDisposePassManager(mpm);
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {
|
unsafe fn add_sanitizer_passes(config: &ModuleConfig, passes: &mut Vec<&'static mut llvm::Pass>) {
|
||||||
|
|
|
@ -2322,13 +2322,13 @@ fn set_members_of_composite_type(
|
||||||
DIB(cx),
|
DIB(cx),
|
||||||
composite_type_metadata,
|
composite_type_metadata,
|
||||||
Some(type_array),
|
Some(type_array),
|
||||||
type_params,
|
Some(type_params),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the type parameters for a type, if any, for the given metadata.
|
/// 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 let ty::Adt(def, substs) = *ty.kind() {
|
||||||
if substs.types().next().is_some() {
|
if substs.types().next().is_some() {
|
||||||
let generics = cx.tcx.generics_of(def.did);
|
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();
|
.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> {
|
fn get_parameter_names(cx: &CodegenCx<'_, '_>, generics: &ty::Generics) -> Vec<Symbol> {
|
||||||
let mut names = generics
|
let mut names = generics
|
||||||
|
|
|
@ -160,7 +160,7 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
||||||
module: &ModuleCodegen<Self::Module>,
|
module: &ModuleCodegen<Self::Module>,
|
||||||
config: &ModuleConfig,
|
config: &ModuleConfig,
|
||||||
) -> Result<(), FatalError> {
|
) -> Result<(), FatalError> {
|
||||||
back::write::optimize(cgcx, diag_handler, module, config)
|
Ok(back::write::optimize(cgcx, diag_handler, module, config))
|
||||||
}
|
}
|
||||||
unsafe fn optimize_thin(
|
unsafe fn optimize_thin(
|
||||||
cgcx: &CodegenContext<Self>,
|
cgcx: &CodegenContext<Self>,
|
||||||
|
|
|
@ -522,7 +522,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||||
mut bx: Bx,
|
mut bx: Bx,
|
||||||
terminator: &mir::Terminator<'tcx>,
|
terminator: &mir::Terminator<'tcx>,
|
||||||
func: &mir::Operand<'tcx>,
|
func: &mir::Operand<'tcx>,
|
||||||
args: &Vec<mir::Operand<'tcx>>,
|
args: &[mir::Operand<'tcx>],
|
||||||
destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>,
|
destination: &Option<(mir::Place<'tcx>, mir::BasicBlock)>,
|
||||||
cleanup: Option<mir::BasicBlock>,
|
cleanup: Option<mir::BasicBlock>,
|
||||||
fn_span: Span,
|
fn_span: Span,
|
||||||
|
|
|
@ -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(|| {
|
let pager_name = env::var_os("PAGER").unwrap_or_else(|| {
|
||||||
if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") }
|
if cfg!(windows) { OsString::from("more.com") } else { OsString::from("less") }
|
||||||
});
|
});
|
||||||
|
|
|
@ -417,7 +417,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
|
||||||
// obviously it never weeds out ALL errors.
|
// obviously it never weeds out ALL errors.
|
||||||
fn process_errors(
|
fn process_errors(
|
||||||
&self,
|
&self,
|
||||||
errors: &Vec<RegionResolutionError<'tcx>>,
|
errors: &[RegionResolutionError<'tcx>],
|
||||||
) -> Vec<RegionResolutionError<'tcx>> {
|
) -> Vec<RegionResolutionError<'tcx>> {
|
||||||
debug!("process_errors()");
|
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)) {
|
let mut errors = if errors.iter().all(|e| is_bound_failure(e)) {
|
||||||
errors.clone()
|
errors.to_owned()
|
||||||
} else {
|
} else {
|
||||||
errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
|
errors.iter().filter(|&e| !is_bound_failure(e)).cloned().collect()
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,8 +5,8 @@ use syn::parse::{Parse, ParseStream, Result};
|
||||||
use syn::punctuated::Punctuated;
|
use syn::punctuated::Punctuated;
|
||||||
use syn::spanned::Spanned;
|
use syn::spanned::Spanned;
|
||||||
use syn::{
|
use syn::{
|
||||||
braced, parenthesized, parse_macro_input, AttrStyle, Attribute, Block, Error, Expr, Ident,
|
braced, parenthesized, parse_macro_input, parse_quote, AttrStyle, Attribute, Block, Error,
|
||||||
ReturnType, Token, Type,
|
Expr, Ident, ReturnType, Token, Type,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod kw {
|
mod kw {
|
||||||
|
@ -272,6 +272,40 @@ fn process_modifiers(query: &mut Query) -> QueryModifiers {
|
||||||
if desc.is_some() {
|
if desc.is_some() {
|
||||||
panic!("duplicate modifier `desc` for query `{}`", query.name);
|
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));
|
desc = Some((tcx, list));
|
||||||
}
|
}
|
||||||
QueryModifier::FatalCycle => {
|
QueryModifier::FatalCycle => {
|
||||||
|
|
|
@ -574,7 +574,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
|
||||||
/// format!("Expected a point greater than ({x}, {y})", x = self.x, y = self.y)
|
/// format!("Expected a point greater than ({x}, {y})", x = self.x, y = self.y)
|
||||||
/// ```
|
/// ```
|
||||||
/// This function builds the entire call to format!.
|
/// 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,
|
// 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
|
// the iteration order needs to be deterministic, hence why we use a BTreeSet here instead
|
||||||
// of a HashSet.
|
// of a HashSet.
|
||||||
|
|
|
@ -954,7 +954,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
target_place: PlaceRef<'tcx>,
|
target_place: PlaceRef<'tcx>,
|
||||||
places: &Vec<Operand<'tcx>>,
|
places: &[Operand<'tcx>],
|
||||||
) -> Option<(Span, Option<GeneratorKind>, Span)> {
|
) -> Option<(Span, Option<GeneratorKind>, Span)> {
|
||||||
debug!(
|
debug!(
|
||||||
"closure_span: def_id={:?} target_place={:?} places={:?}",
|
"closure_span: def_id={:?} target_place={:?} places={:?}",
|
||||||
|
|
|
@ -58,11 +58,7 @@ impl vll::LinkElem for Appearance {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LocalUseMap {
|
impl LocalUseMap {
|
||||||
crate fn build(
|
crate fn build(live_locals: &[Local], elements: &RegionValueElements, body: &Body<'_>) -> Self {
|
||||||
live_locals: &Vec<Local>,
|
|
||||||
elements: &RegionValueElements,
|
|
||||||
body: &Body<'_>,
|
|
||||||
) -> Self {
|
|
||||||
let nones = IndexVec::from_elem_n(None, body.local_decls.len());
|
let nones = IndexVec::from_elem_n(None, body.local_decls.len());
|
||||||
let mut local_use_map = LocalUseMap {
|
let mut local_use_map = LocalUseMap {
|
||||||
first_def_at: nones.clone(),
|
first_def_at: nones.clone(),
|
||||||
|
|
|
@ -153,7 +153,7 @@ impl<T: Copy + Eq + Hash + std::fmt::Debug, PATH: Default> RefTracking<T, PATH>
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Format a path
|
/// Format a path
|
||||||
fn write_path(out: &mut String, path: &Vec<PathElem>) {
|
fn write_path(out: &mut String, path: &[PathElem]) {
|
||||||
use self::PathElem::*;
|
use self::PathElem::*;
|
||||||
|
|
||||||
for elem in path.iter() {
|
for elem in path.iter() {
|
||||||
|
|
|
@ -140,7 +140,7 @@ impl<'a> BcbCounters<'a> {
|
||||||
/// message for subsequent debugging.
|
/// message for subsequent debugging.
|
||||||
fn make_bcb_counters(
|
fn make_bcb_counters(
|
||||||
&mut self,
|
&mut self,
|
||||||
coverage_spans: &Vec<CoverageSpan>,
|
coverage_spans: &[CoverageSpan],
|
||||||
) -> Result<Vec<CoverageKind>, Error> {
|
) -> Result<Vec<CoverageKind>, Error> {
|
||||||
debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
|
debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
|
||||||
let num_bcbs = self.basic_coverage_blocks.num_nodes();
|
let num_bcbs = self.basic_coverage_blocks.num_nodes();
|
||||||
|
@ -465,7 +465,7 @@ impl<'a> BcbCounters<'a> {
|
||||||
fn choose_preferred_expression_branch(
|
fn choose_preferred_expression_branch(
|
||||||
&self,
|
&self,
|
||||||
traversal: &TraverseCoverageGraphWithLoops,
|
traversal: &TraverseCoverageGraphWithLoops,
|
||||||
branches: &Vec<BcbBranch>,
|
branches: &[BcbBranch],
|
||||||
) -> BcbBranch {
|
) -> BcbBranch {
|
||||||
let branch_needs_a_counter =
|
let branch_needs_a_counter =
|
||||||
|branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
|
|branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
|
||||||
|
@ -509,7 +509,7 @@ impl<'a> BcbCounters<'a> {
|
||||||
fn find_some_reloop_branch(
|
fn find_some_reloop_branch(
|
||||||
&self,
|
&self,
|
||||||
traversal: &TraverseCoverageGraphWithLoops,
|
traversal: &TraverseCoverageGraphWithLoops,
|
||||||
branches: &Vec<BcbBranch>,
|
branches: &[BcbBranch],
|
||||||
) -> Option<BcbBranch> {
|
) -> Option<BcbBranch> {
|
||||||
let branch_needs_a_counter =
|
let branch_needs_a_counter =
|
||||||
|branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
|
|branch: &BcbBranch| branch.counter(&self.basic_coverage_blocks).is_none();
|
||||||
|
|
|
@ -99,7 +99,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> {
|
||||||
&self,
|
&self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
substs_ref: SubstsRef<'tcx>,
|
substs_ref: SubstsRef<'tcx>,
|
||||||
args: &Vec<Operand<'tcx>>,
|
args: &[Operand<'tcx>],
|
||||||
source_info: SourceInfo,
|
source_info: SourceInfo,
|
||||||
) {
|
) {
|
||||||
let param_env = self.tcx.param_env(def_id);
|
let param_env = self.tcx.param_env(def_id);
|
||||||
|
@ -162,7 +162,7 @@ impl<'a, 'tcx> FunctionItemRefChecker<'a, 'tcx> {
|
||||||
.unwrap_or(None)
|
.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] {
|
match &args[n] {
|
||||||
Operand::Copy(place) | Operand::Move(place) => {
|
Operand::Copy(place) | Operand::Move(place) => {
|
||||||
self.body.local_decls[place.local].source_info.span
|
self.body.local_decls[place.local].source_info.span
|
||||||
|
|
|
@ -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
|
/// 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.
|
/// projection that isn't captured by a closure.
|
||||||
fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
|
fn convert_to_hir_projections_and_truncate_for_capture<'tcx>(
|
||||||
mir_projections: &Vec<PlaceElem<'tcx>>,
|
mir_projections: &[PlaceElem<'tcx>],
|
||||||
) -> Vec<HirProjectionKind> {
|
) -> Vec<HirProjectionKind> {
|
||||||
|
|
||||||
let mut hir_projections = Vec::new();
|
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.
|
/// list are being applied to the same root variable.
|
||||||
fn is_ancestor_or_same_capture(
|
fn is_ancestor_or_same_capture(
|
||||||
proj_possible_ancestor: &Vec<HirProjectionKind>,
|
proj_possible_ancestor: &Vec<HirProjectionKind>,
|
||||||
proj_capture: &Vec<HirProjectionKind>,
|
proj_capture: &[HirProjectionKind],
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// We want to make sure `is_ancestor_or_same_capture("x.0.0", "x.0")` to return false.
|
// 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.
|
// 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>,
|
typeck_results: &'a ty::TypeckResults<'tcx>,
|
||||||
var_hir_id: HirId,
|
var_hir_id: HirId,
|
||||||
closure_def_id: DefId,
|
closure_def_id: DefId,
|
||||||
projections: &Vec<PlaceElem<'tcx>>,
|
projections: &[PlaceElem<'tcx>],
|
||||||
) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> {
|
) -> Option<(usize, &'a ty::CapturedPlace<'tcx>)> {
|
||||||
let closure_min_captures = typeck_results.closure_min_captures.get(&closure_def_id)?;
|
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)?;
|
let root_variable_min_captures = closure_min_captures.get(&var_hir_id)?;
|
||||||
|
|
|
@ -721,13 +721,9 @@ impl<'a> Parser<'a> {
|
||||||
Ok(t) => {
|
Ok(t) => {
|
||||||
// Parsed successfully, therefore most probably the code only
|
// Parsed successfully, therefore most probably the code only
|
||||||
// misses a separator.
|
// 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
|
expect_err
|
||||||
.span_suggestion_short(
|
.span_suggestion_short(
|
||||||
exp_span,
|
sp,
|
||||||
&format!("missing `{}`", token_str),
|
&format!("missing `{}`", token_str),
|
||||||
token_str,
|
token_str,
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
|
|
|
@ -185,15 +185,15 @@ impl<'a> Resolver<'a> {
|
||||||
|
|
||||||
crate fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
|
crate fn get_macro(&mut self, res: Res) -> Option<Lrc<SyntaxExtension>> {
|
||||||
match res {
|
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())),
|
Res::NonMacroAttr(attr_kind) => Some(self.non_macro_attr(attr_kind.is_used())),
|
||||||
_ => None,
|
_ => 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) {
|
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) {
|
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());
|
self.macro_map.insert(def_id, ext.clone());
|
||||||
Some(ext)
|
ext
|
||||||
}
|
}
|
||||||
|
|
||||||
crate fn build_reduced_graph(
|
crate fn build_reduced_graph(
|
||||||
|
|
|
@ -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.
|
/// When evaluating a `trait` use its associated types' idents for suggestions in E0412.
|
||||||
fn with_trait_items<T>(
|
fn with_trait_items<T>(
|
||||||
&mut self,
|
&mut self,
|
||||||
trait_items: &'ast Vec<P<AssocItem>>,
|
trait_items: &'ast [P<AssocItem>],
|
||||||
f: impl FnOnce(&mut Self) -> T,
|
f: impl FnOnce(&mut Self) -> T,
|
||||||
) -> T {
|
) -> T {
|
||||||
let trait_assoc_items = replace(
|
let trait_assoc_items =
|
||||||
&mut self.diagnostic_metadata.current_trait_assoc_items,
|
replace(&mut self.diagnostic_metadata.current_trait_assoc_items, Some(&trait_items));
|
||||||
Some(&trait_items[..]),
|
|
||||||
);
|
|
||||||
let result = f(self);
|
let result = f(self);
|
||||||
self.diagnostic_metadata.current_trait_assoc_items = trait_assoc_items;
|
self.diagnostic_metadata.current_trait_assoc_items = trait_assoc_items;
|
||||||
result
|
result
|
||||||
|
|
|
@ -1991,14 +1991,13 @@ impl<'a> Resolver<'a> {
|
||||||
{
|
{
|
||||||
// The macro is a proc macro derive
|
// The macro is a proc macro derive
|
||||||
if let Some(def_id) = module.expansion.expn_data().macro_def_id {
|
if let Some(def_id) = module.expansion.expn_data().macro_def_id {
|
||||||
if let Some(ext) = self.get_macro_by_def_id(def_id) {
|
let ext = self.get_macro_by_def_id(def_id);
|
||||||
if !ext.is_builtin
|
if !ext.is_builtin
|
||||||
&& ext.macro_kind() == MacroKind::Derive
|
&& ext.macro_kind() == MacroKind::Derive
|
||||||
&& parent.expansion.outer_expn_is_descendant_of(span.ctxt())
|
&& parent.expansion.outer_expn_is_descendant_of(span.ctxt())
|
||||||
{
|
{
|
||||||
*poisoned = Some(node_id);
|
*poisoned = Some(node_id);
|
||||||
return module.parent;
|
return module.parent;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ impl<'a> FileSearch<'a> {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
sysroot: &'a Path,
|
sysroot: &'a Path,
|
||||||
triple: &'a str,
|
triple: &'a str,
|
||||||
search_paths: &'a Vec<SearchPath>,
|
search_paths: &'a [SearchPath],
|
||||||
tlib_path: &'a SearchPath,
|
tlib_path: &'a SearchPath,
|
||||||
kind: PathKind,
|
kind: PathKind,
|
||||||
) -> FileSearch<'a> {
|
) -> FileSearch<'a> {
|
||||||
|
|
|
@ -247,7 +247,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
|
|
||||||
let mut candidates = SelectionCandidateSet { vec: Vec::new(), ambiguous: false };
|
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
|
// Other bounds. Consider both in-scope bounds from fn decl
|
||||||
// and applicable impls. There is a certain set of precedence rules here.
|
// 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
|
// User-defined copy impls are permitted, but only for
|
||||||
// structs and enums.
|
// 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.
|
// For other types, we'll use the builtin rules.
|
||||||
let copy_conditions = self.copy_clone_conditions(obligation);
|
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) {
|
} else if lang_items.discriminant_kind_trait() == Some(def_id) {
|
||||||
// `DiscriminantKind` is automatically implemented for every type.
|
// `DiscriminantKind` is automatically implemented for every type.
|
||||||
candidates.vec.push(DiscriminantKindCandidate);
|
candidates.vec.push(DiscriminantKindCandidate);
|
||||||
|
@ -271,7 +271,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// Sized is never implementable by end-users, it is
|
// Sized is never implementable by end-users, it is
|
||||||
// always automatically computed.
|
// always automatically computed.
|
||||||
let sized_conditions = self.sized_conditions(obligation);
|
let sized_conditions = self.sized_conditions(obligation);
|
||||||
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates)?;
|
self.assemble_builtin_bound_candidates(sized_conditions, &mut candidates);
|
||||||
} else if lang_items.unsize_trait() == Some(def_id) {
|
} else if lang_items.unsize_trait() == Some(def_id) {
|
||||||
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
|
self.assemble_candidates_for_unsizing(obligation, &mut candidates);
|
||||||
} else {
|
} else {
|
||||||
|
@ -280,13 +280,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
// for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
|
// for `Copy` also has builtin support for `Clone`, and tuples/arrays of `Clone`
|
||||||
// types have builtin support for `Clone`.
|
// types have builtin support for `Clone`.
|
||||||
let clone_conditions = self.copy_clone_conditions(obligation);
|
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_generator_candidates(obligation, &mut candidates);
|
||||||
self.assemble_closure_candidates(obligation, &mut candidates)?;
|
self.assemble_closure_candidates(obligation, &mut candidates);
|
||||||
self.assemble_fn_pointer_candidates(obligation, &mut candidates)?;
|
self.assemble_fn_pointer_candidates(obligation, &mut candidates);
|
||||||
self.assemble_candidates_from_impls(obligation, &mut candidates)?;
|
self.assemble_candidates_from_impls(obligation, &mut candidates);
|
||||||
self.assemble_candidates_from_object_ty(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
|
// Auto implementations have lower priority, so we only
|
||||||
// consider triggering a default if there is no other impl that can apply.
|
// consider triggering a default if there is no other impl that can apply.
|
||||||
if candidates.vec.is_empty() {
|
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());
|
debug!("candidate list size: {}", candidates.vec.len());
|
||||||
Ok(candidates)
|
Ok(candidates)
|
||||||
|
@ -367,9 +367,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) {
|
||||||
if self.tcx().lang_items().gen_trait() != Some(obligation.predicate.def_id()) {
|
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
|
// 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 :
|
/// 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,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) {
|
||||||
let kind = match self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) {
|
let kind = match self.tcx().fn_trait_kind_from_lang_item(obligation.predicate.def_id()) {
|
||||||
Some(k) => k,
|
Some(k) => k,
|
||||||
None => {
|
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.
|
/// Implements one of the `Fn()` family for a fn pointer.
|
||||||
|
@ -444,10 +440,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) {
|
||||||
// We provide impl of all fn traits for fn pointers.
|
// 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() {
|
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.
|
// 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`.
|
/// Searches for impls that might apply to `obligation`.
|
||||||
|
@ -494,7 +488,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) {
|
||||||
debug!(?obligation, "assemble_candidates_from_impls");
|
debug!(?obligation, "assemble_candidates_from_impls");
|
||||||
|
|
||||||
// Essentially any user-written impl will match with an error type,
|
// 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
|
// Since compilation is already guaranteed to fail, this is just
|
||||||
// to try to show the 'nicest' possible errors to the user.
|
// to try to show the 'nicest' possible errors to the user.
|
||||||
if obligation.references_error() {
|
if obligation.references_error() {
|
||||||
return Ok(());
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tcx().for_each_relevant_impl(
|
self.tcx().for_each_relevant_impl(
|
||||||
|
@ -518,15 +512,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assemble_candidates_from_auto_impls(
|
fn assemble_candidates_from_auto_impls(
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) {
|
||||||
// Okay to skip binder here because the tests we do below do not involve bound regions.
|
// Okay to skip binder here because the tests we do below do not involve bound regions.
|
||||||
let self_ty = obligation.self_ty().skip_binder();
|
let self_ty = obligation.self_ty().skip_binder();
|
||||||
debug!(?self_ty, "assemble_candidates_from_auto_impls");
|
debug!(?self_ty, "assemble_candidates_from_auto_impls");
|
||||||
|
@ -585,8 +577,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
_ => candidates.vec.push(AutoImplCandidate(def_id)),
|
_ => candidates.vec.push(AutoImplCandidate(def_id)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Searches for impls that might apply to `obligation`.
|
/// Searches for impls that might apply to `obligation`.
|
||||||
|
@ -753,7 +743,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
obligation: &TraitObligation<'tcx>,
|
obligation: &TraitObligation<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) {
|
||||||
// Okay to skip binder here because the tests we do below do not involve bound regions.
|
// Okay to skip binder here because the tests we do below do not involve bound regions.
|
||||||
let self_ty = obligation.self_ty().skip_binder();
|
let self_ty = obligation.self_ty().skip_binder();
|
||||||
debug!(?self_ty, "assemble_candidates_for_trait_alias");
|
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) {
|
if self.tcx().is_trait_alias(def_id) {
|
||||||
candidates.vec.push(TraitAliasCandidate(def_id));
|
candidates.vec.push(TraitAliasCandidate(def_id));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Assembles the trait which are built-in to the language itself:
|
/// Assembles the trait which are built-in to the language itself:
|
||||||
|
@ -773,7 +761,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
conditions: BuiltinImplConditions<'tcx>,
|
conditions: BuiltinImplConditions<'tcx>,
|
||||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||||
) -> Result<(), SelectionError<'tcx>> {
|
) {
|
||||||
match conditions {
|
match conditions {
|
||||||
BuiltinImplConditions::Where(nested) => {
|
BuiltinImplConditions::Where(nested) => {
|
||||||
debug!(?nested, "builtin_bound");
|
debug!(?nested, "builtin_bound");
|
||||||
|
@ -787,7 +775,5 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||||
candidates.ambiguous = true;
|
candidates.ambiguous = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,15 +267,13 @@ crate fn check_drop_obligations<'a, 'tcx>(
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
body_id: hir::HirId,
|
body_id: hir::HirId,
|
||||||
) -> Result<(), ErrorReported> {
|
) {
|
||||||
debug!("check_drop_obligations typ: {:?}", ty);
|
debug!("check_drop_obligations typ: {:?}", ty);
|
||||||
|
|
||||||
let cause = &ObligationCause::misc(span, body_id);
|
let cause = &ObligationCause::misc(span, body_id);
|
||||||
let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty);
|
let infer_ok = rcx.infcx.at(cause, rcx.fcx.param_env).dropck_outlives(ty);
|
||||||
debug!("dropck_outlives = {:#?}", infer_ok);
|
debug!("dropck_outlives = {:#?}", infer_ok);
|
||||||
rcx.fcx.register_infer_ok_obligations(infer_ok);
|
rcx.fcx.register_infer_ok_obligations(infer_ok);
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an implementation of the TypeRelation trait with the
|
// This is an implementation of the TypeRelation trait with the
|
||||||
|
|
|
@ -423,9 +423,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
probe_cx.assemble_inherent_candidates();
|
probe_cx.assemble_inherent_candidates();
|
||||||
match scope {
|
match scope {
|
||||||
ProbeScope::TraitsInScope => {
|
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)
|
op(probe_cx)
|
||||||
})
|
})
|
||||||
|
@ -866,35 +866,29 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assemble_extension_candidates_for_traits_in_scope(
|
fn assemble_extension_candidates_for_traits_in_scope(&mut self, expr_hir_id: hir::HirId) {
|
||||||
&mut self,
|
|
||||||
expr_hir_id: hir::HirId,
|
|
||||||
) -> Result<(), MethodError<'tcx>> {
|
|
||||||
let mut duplicates = FxHashSet::default();
|
let mut duplicates = FxHashSet::default();
|
||||||
let opt_applicable_traits = self.tcx.in_scope_traits(expr_hir_id);
|
let opt_applicable_traits = self.tcx.in_scope_traits(expr_hir_id);
|
||||||
if let Some(applicable_traits) = opt_applicable_traits {
|
if let Some(applicable_traits) = opt_applicable_traits {
|
||||||
for trait_candidate in applicable_traits.iter() {
|
for trait_candidate in applicable_traits.iter() {
|
||||||
let trait_did = trait_candidate.def_id;
|
let trait_did = trait_candidate.def_id;
|
||||||
if duplicates.insert(trait_did) {
|
if duplicates.insert(trait_did) {
|
||||||
let result = self.assemble_extension_candidates_for_trait(
|
self.assemble_extension_candidates_for_trait(
|
||||||
&trait_candidate.import_ids,
|
&trait_candidate.import_ids,
|
||||||
trait_did,
|
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();
|
let mut duplicates = FxHashSet::default();
|
||||||
for trait_info in suggest::all_traits(self.tcx) {
|
for trait_info in suggest::all_traits(self.tcx) {
|
||||||
if duplicates.insert(trait_info.def_id) {
|
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(
|
pub fn matches_return_type(
|
||||||
|
@ -932,7 +926,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
&mut self,
|
&mut self,
|
||||||
import_ids: &SmallVec<[LocalDefId; 1]>,
|
import_ids: &SmallVec<[LocalDefId; 1]>,
|
||||||
trait_def_id: DefId,
|
trait_def_id: DefId,
|
||||||
) -> Result<(), MethodError<'tcx>> {
|
) {
|
||||||
debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id);
|
debug!("assemble_extension_candidates_for_trait(trait_def_id={:?})", trait_def_id);
|
||||||
let trait_substs = self.fresh_item_substs(trait_def_id);
|
let trait_substs = self.fresh_item_substs(trait_def_id);
|
||||||
let trait_ref = ty::TraitRef::new(trait_def_id, trait_substs);
|
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> {
|
fn candidate_method_names(&self) -> Vec<Ident> {
|
||||||
|
@ -1027,7 +1020,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
||||||
let span = self.span;
|
let span = self.span;
|
||||||
let tcx = self.tcx;
|
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() {
|
let out_of_scope_traits = match self.pick_core() {
|
||||||
Some(Ok(p)) => vec![p.item.container.id()],
|
Some(Ok(p)) => vec![p.item.container.id()],
|
||||||
|
|
|
@ -325,7 +325,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
|
||||||
pat.each_binding(|_, hir_id, span, _| {
|
pat.each_binding(|_, hir_id, span, _| {
|
||||||
let typ = self.resolve_node_type(hir_id);
|
let typ = self.resolve_node_type(hir_id);
|
||||||
let body_id = self.body_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() {
|
if place_with_id.place.projections.is_empty() {
|
||||||
let typ = self.resolve_type(place_with_id.place.ty());
|
let typ = self.resolve_type(place_with_id.place.ty());
|
||||||
let body_id = self.body_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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,11 +14,13 @@
|
||||||
#![feature(core_intrinsics)]
|
#![feature(core_intrinsics)]
|
||||||
#![feature(nll)]
|
#![feature(nll)]
|
||||||
#![feature(panic_runtime)]
|
#![feature(panic_runtime)]
|
||||||
|
#![feature(std_internals)]
|
||||||
#![feature(staged_api)]
|
#![feature(staged_api)]
|
||||||
#![feature(rustc_attrs)]
|
#![feature(rustc_attrs)]
|
||||||
#![feature(asm)]
|
#![feature(asm)]
|
||||||
|
|
||||||
use core::any::Any;
|
use core::any::Any;
|
||||||
|
use core::panic::BoxMeUp;
|
||||||
|
|
||||||
#[rustc_std_internal_symbol]
|
#[rustc_std_internal_symbol]
|
||||||
#[allow(improper_ctypes_definitions)]
|
#[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.
|
// "Leak" the payload and shim to the relevant abort on the platform in question.
|
||||||
#[rustc_std_internal_symbol]
|
#[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();
|
abort();
|
||||||
|
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
|
|
|
@ -104,9 +104,8 @@ pub unsafe extern "C" fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any
|
||||||
// implementation.
|
// implementation.
|
||||||
#[rustc_std_internal_symbol]
|
#[rustc_std_internal_symbol]
|
||||||
#[unwind(allowed)]
|
#[unwind(allowed)]
|
||||||
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 {
|
||||||
let payload = payload as *mut &mut dyn BoxMeUp;
|
let payload = Box::from_raw((*payload).take_box());
|
||||||
let payload = (*payload).take_box();
|
|
||||||
|
|
||||||
imp::panic(Box::from_raw(payload))
|
imp::panic(payload)
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,11 @@ use realstd::io::set_output_capture;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
fn __rust_panic_cleanup(payload: *mut u8) -> *mut (dyn Any + Send + 'static);
|
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.
|
/// `payload` is passed through another layer of raw pointers as `&mut dyn Trait` is not
|
||||||
/// It cannot be `Box<dyn BoxMeUp>` because the other end of this call does not depend
|
/// FFI-safe. `BoxMeUp` lazily performs allocation only when needed (this avoids allocations
|
||||||
/// on liballoc, and thus cannot use `Box`.
|
/// when using the "abort" panic runtime).
|
||||||
#[unwind(allowed)]
|
#[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
|
/// 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) -> ! {
|
fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! {
|
||||||
let code = unsafe {
|
let code = unsafe {
|
||||||
let obj = &mut msg as *mut &mut dyn BoxMeUp;
|
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)
|
rtabort!("failed to initiate panic, error {}", code)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,17 +4,21 @@
|
||||||
<DisplayString>{data_ptr,[length]s8}</DisplayString>
|
<DisplayString>{data_ptr,[length]s8}</DisplayString>
|
||||||
<StringView>data_ptr,[length]s8</StringView>
|
<StringView>data_ptr,[length]s8</StringView>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">length</Item>
|
<Item Name="[len]" ExcludeView="simple">length</Item>
|
||||||
<ArrayItems>
|
<Synthetic Name="[chars]">
|
||||||
<Size>length</Size>
|
<Expand>
|
||||||
<ValuePointer>data_ptr</ValuePointer>
|
<ArrayItems>
|
||||||
</ArrayItems>
|
<Size>length</Size>
|
||||||
|
<ValuePointer>data_ptr</ValuePointer>
|
||||||
|
</ArrayItems>
|
||||||
|
</Expand>
|
||||||
|
</Synthetic>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
<Type Name="slice<*>">
|
<Type Name="slice<*>">
|
||||||
<DisplayString>{{ length={length} }}</DisplayString>
|
<DisplayString>{{ len={length} }}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">length</Item>
|
<Item Name="[len]" ExcludeView="simple">length</Item>
|
||||||
<ArrayItems>
|
<ArrayItems>
|
||||||
<Size>length</Size>
|
<Size>length</Size>
|
||||||
<ValuePointer>data_ptr</ValuePointer>
|
<ValuePointer>data_ptr</ValuePointer>
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
|
||||||
<Type Name="alloc::vec::Vec<*>">
|
<Type Name="alloc::vec::Vec<*>">
|
||||||
<DisplayString>{{ size={len} }}</DisplayString>
|
<DisplayString>{{ len={len} }}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">len</Item>
|
<Item Name="[len]" ExcludeView="simple">len</Item>
|
||||||
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
|
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
|
||||||
<ArrayItems>
|
<ArrayItems>
|
||||||
<Size>len</Size>
|
<Size>len</Size>
|
||||||
|
@ -12,9 +12,9 @@
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
<Type Name="alloc::collections::vec_deque::VecDeque<*>">
|
<Type Name="alloc::collections::vec_deque::VecDeque<*>">
|
||||||
<DisplayString>{{ size={tail <= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
|
<DisplayString>{{ len={tail <= head ? head - tail : buf.cap - tail + head} }}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">tail <= head ? head - tail : buf.cap - tail + head</Item>
|
<Item Name="[len]" ExcludeView="simple">tail <= head ? head - tail : buf.cap - tail + head</Item>
|
||||||
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
|
<Item Name="[capacity]" ExcludeView="simple">buf.cap</Item>
|
||||||
<CustomListItems>
|
<CustomListItems>
|
||||||
<Variable Name="i" InitialValue="tail" />
|
<Variable Name="i" InitialValue="tail" />
|
||||||
|
@ -31,7 +31,7 @@
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
<Type Name="alloc::collections::linked_list::LinkedList<*>">
|
<Type Name="alloc::collections::linked_list::LinkedList<*>">
|
||||||
<DisplayString>{{ size={len} }}</DisplayString>
|
<DisplayString>{{ len={len} }}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<LinkedListItems>
|
<LinkedListItems>
|
||||||
<Size>len</Size>
|
<Size>len</Size>
|
||||||
|
@ -42,15 +42,37 @@
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
<Type Name="alloc::string::String">
|
<Type Name="alloc::string::String">
|
||||||
<DisplayString>{*(char**)this,[vec.len]s8}</DisplayString>
|
<DisplayString>{(char*)vec.buf.ptr.pointer,[vec.len]s8}</DisplayString>
|
||||||
<StringView>*(char**)this,[vec.len]s8</StringView>
|
<StringView>(char*)vec.buf.ptr.pointer,[vec.len]s8</StringView>
|
||||||
<Expand>
|
<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>
|
<Item Name="[capacity]" ExcludeView="simple">vec.buf.cap</Item>
|
||||||
<ArrayItems>
|
<Synthetic Name="[chars]">
|
||||||
<Size>vec.len</Size>
|
<Expand>
|
||||||
<ValuePointer>*(char**)this</ValuePointer>
|
<ArrayItems>
|
||||||
</ArrayItems>
|
<Size>vec.len</Size>
|
||||||
|
<ValuePointer>(char*)vec.buf.ptr.pointer</ValuePointer>
|
||||||
|
</ArrayItems>
|
||||||
|
</Expand>
|
||||||
|
</Synthetic>
|
||||||
|
</Expand>
|
||||||
|
</Type>
|
||||||
|
<Type Name="alloc::rc::Rc<*>">
|
||||||
|
<DisplayString>{ptr.pointer->value}</DisplayString>
|
||||||
|
<Expand>
|
||||||
|
<ExpandedItem>ptr.pointer->value</ExpandedItem>
|
||||||
|
</Expand>
|
||||||
|
</Type>
|
||||||
|
<Type Name="alloc::sync::Arc<*>">
|
||||||
|
<DisplayString>{ptr.pointer->data}</DisplayString>
|
||||||
|
<Expand>
|
||||||
|
<ExpandedItem>ptr.pointer->data</ExpandedItem>
|
||||||
|
</Expand>
|
||||||
|
</Type>
|
||||||
|
<Type Name="alloc::sync::Weak<*>">
|
||||||
|
<DisplayString>{ptr.pointer->data}</DisplayString>
|
||||||
|
<Expand>
|
||||||
|
<ExpandedItem>ptr.pointer->data</ExpandedItem>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
</AutoVisualizer>
|
</AutoVisualizer>
|
||||||
|
|
|
@ -6,34 +6,28 @@
|
||||||
<Item Name="[ptr]">pointer</Item>
|
<Item Name="[ptr]">pointer</Item>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
<Type Name="core::ptr::Shared<*>">
|
<Type Name="core::ptr::Shared<*>">
|
||||||
<DisplayString>{{ Shared {pointer} }}</DisplayString>
|
<DisplayString>{{ Shared {pointer} }}</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[ptr]">pointer</Item>
|
<Item Name="[ptr]">pointer</Item>
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
<Type Name="core::option::Option<*>">
|
<Type Name="core::option::Option<*>">
|
||||||
<DisplayString Condition="RUST$ENUM$DISR == 0x0">{{ None }}</DisplayString>
|
<DisplayString Condition="RUST$ENUM$DISR == 0x0">None</DisplayString>
|
||||||
<DisplayString Condition="RUST$ENUM$DISR == 0x1">{{ Some {__0} }}</DisplayString>
|
<DisplayString Condition="RUST$ENUM$DISR == 0x1">Some({__0})</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">(ULONG)(RUST$ENUM$DISR != 0)</Item>
|
<Item Name="[value]" ExcludeView="simple" Condition="RUST$ENUM$DISR == 1">__0</Item>
|
||||||
<Item Name="[value]" ExcludeView="simple">__0</Item>
|
|
||||||
<ArrayItems>
|
|
||||||
<Size>(ULONG)(RUST$ENUM$DISR != 0)</Size>
|
|
||||||
<ValuePointer>&__0</ValuePointer>
|
|
||||||
</ArrayItems>
|
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
<Type Name="core::option::Option<*>" Priority="MediumLow">
|
<Type Name="core::option::Option<*>" Priority="MediumLow">
|
||||||
<DisplayString Condition="*(PVOID *)this == nullptr">{{ None }}</DisplayString>
|
<DisplayString Condition="*(void**)this == nullptr">None</DisplayString>
|
||||||
<DisplayString>{{ Some {($T1 *)this} }}</DisplayString>
|
<DisplayString>Some({($T1 *)this})</DisplayString>
|
||||||
<Expand>
|
<Expand>
|
||||||
<Item Name="[size]" ExcludeView="simple">(ULONG)(*(PVOID *)this != nullptr)</Item>
|
<Item Name="Some" ExcludeView="simple" Condition="*(void**)this != nullptr">($T1 *)this</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>
|
|
||||||
</Expand>
|
</Expand>
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
</AutoVisualizer>
|
</AutoVisualizer>
|
|
@ -26,9 +26,9 @@
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<Type Name="std::collections::hash::map::HashMap<*,*,*>">
|
<Type Name="std::collections::hash::map::HashMap<*,*,*>">
|
||||||
<DisplayString>{{ size={base.table.items} }}</DisplayString>
|
<DisplayString>{{ len={base.table.items} }}</DisplayString>
|
||||||
<Expand>
|
<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="[capacity]">base.table.items + base.table.growth_left</Item>
|
||||||
<Item Name="[state]">base.hash_builder</Item>
|
<Item Name="[state]">base.hash_builder</Item>
|
||||||
|
|
||||||
|
@ -50,9 +50,9 @@
|
||||||
</Type>
|
</Type>
|
||||||
|
|
||||||
<Type Name="std::collections::hash::set::HashSet<*,*>">
|
<Type Name="std::collections::hash::set::HashSet<*,*>">
|
||||||
<DisplayString>{{ size={base.map.table.items} }}</DisplayString>
|
<DisplayString>{{ len={base.map.table.items} }}</DisplayString>
|
||||||
<Expand>
|
<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="[capacity]">base.map.table.items + base.map.table.growth_left</Item>
|
||||||
<Item Name="[state]">base.map.hash_builder</Item>
|
<Item Name="[state]">base.map.hash_builder</Item>
|
||||||
|
|
||||||
|
|
|
@ -3,12 +3,12 @@ use crate::clean::*;
|
||||||
crate struct StripItem(pub Item);
|
crate struct StripItem(pub Item);
|
||||||
|
|
||||||
impl StripItem {
|
impl StripItem {
|
||||||
crate fn strip(self) -> Option<Item> {
|
crate fn strip(self) -> Item {
|
||||||
match self.0 {
|
match self.0 {
|
||||||
Item { kind: box StrippedItem(..), .. } => Some(self.0),
|
Item { kind: box StrippedItem(..), .. } => self.0,
|
||||||
mut i => {
|
mut i => {
|
||||||
i.kind = box StrippedItem(i.kind);
|
i.kind = box StrippedItem(i.kind);
|
||||||
Some(i)
|
i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -418,7 +418,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for LinkReplacer<'a, I> {
|
||||||
struct HeadingLinks<'a, 'b, 'ids, I> {
|
struct HeadingLinks<'a, 'b, 'ids, I> {
|
||||||
inner: I,
|
inner: I,
|
||||||
toc: Option<&'b mut TocBuilder>,
|
toc: Option<&'b mut TocBuilder>,
|
||||||
buf: VecDeque<(Event<'a>, Range<usize>)>,
|
buf: VecDeque<Event<'a>>,
|
||||||
id_map: &'ids mut IdMap,
|
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
|
impl<'a, 'b, 'ids, I: Iterator<Item = Event<'a>>> Iterator for HeadingLinks<'a, 'b, 'ids, I> {
|
||||||
for HeadingLinks<'a, 'b, 'ids, I>
|
type Item = Event<'a>;
|
||||||
{
|
|
||||||
type Item = (Event<'a>, Range<usize>);
|
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if let Some(e) = self.buf.pop_front() {
|
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();
|
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();
|
let mut id = String::new();
|
||||||
for event in &mut self.inner {
|
for event in &mut self.inner {
|
||||||
match &event.0 {
|
match &event {
|
||||||
Event::End(Tag::Heading(..)) => break,
|
Event::End(Tag::Heading(..)) => break,
|
||||||
Event::Start(Tag::Link(_, _, _)) | Event::End(Tag::Link(..)) => {}
|
|
||||||
Event::Text(text) | Event::Code(text) => {
|
Event::Text(text) | Event::Code(text) => {
|
||||||
id.extend(text.chars().filter_map(slugify));
|
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);
|
let id = self.id_map.derive(id);
|
||||||
|
|
||||||
if let Some(ref mut builder) = self.toc {
|
if let Some(ref mut builder) = self.toc {
|
||||||
let mut html_header = String::new();
|
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());
|
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!(
|
let start_tags = format!(
|
||||||
"<h{level} id=\"{id}\" class=\"section-header\">\
|
"<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,
|
id = id,
|
||||||
level = level
|
level = level
|
||||||
);
|
);
|
||||||
return Some((Event::Html(start_tags.into()), 0..0));
|
return Some(Event::Html(start_tags.into()));
|
||||||
}
|
}
|
||||||
event
|
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> {
|
impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Footnotes<'a, I> {
|
||||||
type Item = (Event<'a>, Range<usize>);
|
type Item = Event<'a>;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
loop {
|
loop {
|
||||||
match self.inner.next() {
|
match self.inner.next() {
|
||||||
Some((Event::FootnoteReference(ref reference), range)) => {
|
Some(Event::FootnoteReference(ref reference)) => {
|
||||||
let entry = self.get_entry(&reference);
|
let entry = self.get_entry(&reference);
|
||||||
let reference = format!(
|
let reference = format!(
|
||||||
"<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>",
|
"<sup id=\"fnref{0}\"><a href=\"#fn{0}\">{0}</a></sup>",
|
||||||
(*entry).1
|
(*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();
|
let mut content = Vec::new();
|
||||||
for (event, _) in &mut self.inner {
|
for event in &mut self.inner {
|
||||||
if let Event::End(Tag::FootnoteDefinition(..)) = event {
|
if let Event::End(Tag::FootnoteDefinition(..)) = event {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -607,7 +607,7 @@ impl<'a, I: Iterator<Item = (Event<'a>, Range<usize>)>> Iterator for Footnotes<'
|
||||||
ret.push_str("</li>");
|
ret.push_str("</li>");
|
||||||
}
|
}
|
||||||
ret.push_str("</ol></div>");
|
ret.push_str("</ol></div>");
|
||||||
return Some((Event::Html(ret.into()), 0..0));
|
return Some(Event::Html(ret.into()));
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -917,14 +917,13 @@ impl Markdown<'_> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let p = Parser::new_with_broken_link_callback(md, opts(), Some(&mut replacer));
|
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 mut s = String::with_capacity(md.len() * 3 / 2);
|
||||||
|
|
||||||
let p = HeadingLinks::new(p, None, &mut ids);
|
let p = HeadingLinks::new(p, None, &mut ids);
|
||||||
let p = Footnotes::new(p);
|
let p = LinkReplacer::new(p, links);
|
||||||
let p = LinkReplacer::new(p.map(|(ev, _)| ev), links);
|
|
||||||
let p = CodeBlocks::new(p, codes, edition, playground);
|
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||||
|
let p = Footnotes::new(p);
|
||||||
html::push_html(&mut s, p);
|
html::push_html(&mut s, p);
|
||||||
|
|
||||||
s
|
s
|
||||||
|
@ -935,7 +934,7 @@ impl MarkdownWithToc<'_> {
|
||||||
crate fn into_string(self) -> String {
|
crate fn into_string(self) -> String {
|
||||||
let MarkdownWithToc(md, mut ids, codes, edition, playground) = self;
|
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);
|
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 = HeadingLinks::new(p, Some(&mut toc), &mut ids);
|
||||||
|
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||||
let p = Footnotes::new(p);
|
let p = Footnotes::new(p);
|
||||||
let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
|
|
||||||
html::push_html(&mut s, p);
|
html::push_html(&mut s, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,19 +959,19 @@ impl MarkdownHtml<'_> {
|
||||||
if md.is_empty() {
|
if md.is_empty() {
|
||||||
return String::new();
|
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.
|
// Treat inline HTML as plain text.
|
||||||
let p = p.map(|event| match event.0 {
|
let p = p.map(|event| match event {
|
||||||
Event::Html(text) => (Event::Text(text), event.1),
|
Event::Html(text) => Event::Text(text),
|
||||||
_ => event,
|
_ => event,
|
||||||
});
|
});
|
||||||
|
|
||||||
let mut s = String::with_capacity(md.len() * 3 / 2);
|
let mut s = String::with_capacity(md.len() * 3 / 2);
|
||||||
|
|
||||||
let p = HeadingLinks::new(p, None, &mut ids);
|
let p = HeadingLinks::new(p, None, &mut ids);
|
||||||
|
let p = CodeBlocks::new(p, codes, edition, playground);
|
||||||
let p = Footnotes::new(p);
|
let p = Footnotes::new(p);
|
||||||
let p = CodeBlocks::new(p.map(|(ev, _)| ev), codes, edition, playground);
|
|
||||||
html::push_html(&mut s, p);
|
html::push_html(&mut s, p);
|
||||||
|
|
||||||
s
|
s
|
||||||
|
@ -1125,45 +1124,50 @@ crate fn plain_text_summary(md: &str) -> String {
|
||||||
s
|
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() {
|
if md.is_empty() {
|
||||||
return vec![];
|
return vec![];
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut links = 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 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.
|
let locate = |s: &str| unsafe {
|
||||||
// NOTE: uses `rfind` in case the title and url are the same: `[Ok][Ok]`
|
let s_start = s.as_ptr();
|
||||||
match md[span.clone()].rfind(link) {
|
let s_end = s_start.add(s.len());
|
||||||
Some(start) => {
|
let md_start = md.as_ptr();
|
||||||
let start = span.start + start;
|
let md_end = md_start.add(md.len());
|
||||||
start..start + link.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
|
let mut push = |link: BrokenLink<'_>| {
|
||||||
// the IDs generated aren't going to be emitted anywhere.
|
// FIXME: use `link.span` instead of `locate`
|
||||||
let mut ids = IdMap::new();
|
// (doing it now includes the `[]` as well as the text)
|
||||||
let iter = Footnotes::new(HeadingLinks::new(p.into_offset_iter(), None, &mut ids));
|
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 {
|
// There's no need to thread an IdMap through to here because
|
||||||
if let Event::Start(Tag::Link(_, dest, _)) = ev.0 {
|
// the IDs generated aren't going to be emitted anywhere.
|
||||||
debug!("found link: {}", dest);
|
let mut ids = IdMap::new();
|
||||||
let span = span_for_link(&dest, ev.1);
|
let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids));
|
||||||
links.push((dest.into_string(), span));
|
|
||||||
|
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),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3483,7 +3483,7 @@ enum AssocItemLink<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> AssocItemLink<'a> {
|
impl<'a> AssocItemLink<'a> {
|
||||||
fn anchor(&self, id: &'a String) -> Self {
|
fn anchor(&self, id: &'a str) -> Self {
|
||||||
match *self {
|
match *self {
|
||||||
AssocItemLink::Anchor(_) => AssocItemLink::Anchor(Some(&id)),
|
AssocItemLink::Anchor(_) => AssocItemLink::Anchor(Some(&id)),
|
||||||
ref other => *other,
|
ref other => *other,
|
||||||
|
|
|
@ -245,7 +245,7 @@ struct DiagnosticInfo<'a> {
|
||||||
item: &'a Item,
|
item: &'a Item,
|
||||||
dox: &'a str,
|
dox: &'a str,
|
||||||
ori_link: &'a str,
|
ori_link: &'a str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Hash)]
|
#[derive(Clone, Debug, Hash)]
|
||||||
|
@ -982,7 +982,7 @@ impl LinkCollector<'_, '_> {
|
||||||
parent_node: Option<DefId>,
|
parent_node: Option<DefId>,
|
||||||
krate: CrateNum,
|
krate: CrateNum,
|
||||||
ori_link: String,
|
ori_link: String,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
) -> Option<ItemLink> {
|
) -> Option<ItemLink> {
|
||||||
trace!("considering link '{}'", ori_link);
|
trace!("considering link '{}'", ori_link);
|
||||||
|
|
||||||
|
@ -1628,7 +1628,7 @@ fn report_diagnostic(
|
||||||
msg: &str,
|
msg: &str,
|
||||||
item: &Item,
|
item: &Item,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: &Range<usize>,
|
link_range: &Option<Range<usize>>,
|
||||||
decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
|
decorate: impl FnOnce(&mut DiagnosticBuilder<'_>, Option<rustc_span::Span>),
|
||||||
) {
|
) {
|
||||||
let hir_id = match cx.as_local_hir_id(item.def_id) {
|
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| {
|
cx.tcx.struct_span_lint_hir(lint, hir_id, sp, |lint| {
|
||||||
let mut diag = lint.build(msg);
|
let mut diag = lint.build(msg);
|
||||||
|
|
||||||
let span = super::source_span_for_markdown_range(cx, dox, link_range, attrs);
|
let span = link_range
|
||||||
if let Some(sp) = span {
|
.as_ref()
|
||||||
diag.set_span(sp);
|
.and_then(|range| super::source_span_for_markdown_range(cx, dox, range, attrs));
|
||||||
} 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.
|
if let Some(link_range) = link_range {
|
||||||
diag.note(&format!(
|
if let Some(sp) = span {
|
||||||
"the link appears in this line:\n\n{line}\n\
|
diag.set_span(sp);
|
||||||
{indicator: <before$}{indicator:^<found$}",
|
} else {
|
||||||
line = line,
|
// blah blah blah\nblah\nblah [blah] blah blah\nblah blah
|
||||||
indicator = "",
|
// ^ ~~~~
|
||||||
before = link_range.start - last_new_line_offset,
|
// | link_range
|
||||||
found = link_range.len(),
|
// 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);
|
decorate(&mut diag, span);
|
||||||
|
@ -1685,7 +1690,7 @@ fn resolution_failure(
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
disambiguator: Option<Disambiguator>,
|
disambiguator: Option<Disambiguator>,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
|
kinds: SmallVec<[ResolutionFailure<'_>; 3]>,
|
||||||
) {
|
) {
|
||||||
let tcx = collector.cx.tcx;
|
let tcx = collector.cx.tcx;
|
||||||
|
@ -1909,7 +1914,7 @@ fn anchor_failure(
|
||||||
item: &Item,
|
item: &Item,
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
failure: AnchorFailure,
|
failure: AnchorFailure,
|
||||||
) {
|
) {
|
||||||
let msg = match failure {
|
let msg = match failure {
|
||||||
|
@ -1934,7 +1939,7 @@ fn ambiguity_error(
|
||||||
item: &Item,
|
item: &Item,
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
candidates: Vec<Res>,
|
candidates: Vec<Res>,
|
||||||
) {
|
) {
|
||||||
let mut msg = format!("`{}` is ", path_str);
|
let mut msg = format!("`{}` is ", path_str);
|
||||||
|
@ -1983,12 +1988,13 @@ fn suggest_disambiguator(
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
sp: Option<rustc_span::Span>,
|
sp: Option<rustc_span::Span>,
|
||||||
link_range: &Range<usize>,
|
link_range: &Option<Range<usize>>,
|
||||||
) {
|
) {
|
||||||
let suggestion = disambiguator.suggestion();
|
let suggestion = disambiguator.suggestion();
|
||||||
let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
|
let help = format!("to link to the {}, {}", disambiguator.descr(), suggestion.descr());
|
||||||
|
|
||||||
if let Some(sp) = sp {
|
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'`') {
|
let msg = if dox.bytes().nth(link_range.start) == Some(b'`') {
|
||||||
format!("`{}`", suggestion.as_help(path_str))
|
format!("`{}`", suggestion.as_help(path_str))
|
||||||
} else {
|
} else {
|
||||||
|
@ -2007,7 +2013,7 @@ fn privacy_error(
|
||||||
item: &Item,
|
item: &Item,
|
||||||
path_str: &str,
|
path_str: &str,
|
||||||
dox: &str,
|
dox: &str,
|
||||||
link_range: Range<usize>,
|
link_range: Option<Range<usize>>,
|
||||||
) {
|
) {
|
||||||
let sym;
|
let sym;
|
||||||
let item_name = match item.name {
|
let item_name = match item.name {
|
||||||
|
|
|
@ -49,7 +49,7 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||||
let old = mem::replace(&mut self.update_retained, false);
|
let old = mem::replace(&mut self.update_retained, false);
|
||||||
let ret = StripItem(self.fold_item_recur(i)).strip();
|
let ret = StripItem(self.fold_item_recur(i)).strip();
|
||||||
self.update_retained = old;
|
self.update_retained = old;
|
||||||
return ret;
|
return Some(ret);
|
||||||
}
|
}
|
||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,7 +51,7 @@ impl<'a> DocFolder for Stripper<'a> {
|
||||||
|
|
||||||
clean::StructFieldItem(..) => {
|
clean::StructFieldItem(..) => {
|
||||||
if !i.visibility.is_public() {
|
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 old = mem::replace(&mut self.update_retained, false);
|
||||||
let ret = StripItem(self.fold_item_recur(i)).strip();
|
let ret = StripItem(self.fold_item_recur(i)).strip();
|
||||||
self.update_retained = old;
|
self.update_retained = old;
|
||||||
return ret;
|
return Some(ret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
// cdb-command: g
|
// cdb-command: g
|
||||||
|
|
||||||
// cdb-command: dx hash_set,d
|
// cdb-command: dx hash_set,d
|
||||||
// cdb-check:hash_set,d [...] : { size=15 } [Type: [...]::HashSet<u64, [...]>]
|
// cdb-check:hash_set,d [...] : { len=15 } [Type: [...]::HashSet<u64, [...]>]
|
||||||
// cdb-check: [size] : 15 [Type: [...]]
|
// cdb-check: [len] : 15 [Type: [...]]
|
||||||
// cdb-check: [capacity] : [...]
|
// cdb-check: [capacity] : [...]
|
||||||
// cdb-check: [[...]] [...] : 0 [Type: u64]
|
// cdb-check: [[...]] [...] : 0 [Type: u64]
|
||||||
// cdb-command: dx hash_set,d
|
// cdb-command: dx hash_set,d
|
||||||
|
@ -44,8 +44,8 @@
|
||||||
// cdb-check: [[...]] [...] : 14 [Type: u64]
|
// cdb-check: [[...]] [...] : 14 [Type: u64]
|
||||||
|
|
||||||
// cdb-command: dx hash_map,d
|
// cdb-command: dx hash_map,d
|
||||||
// cdb-check:hash_map,d [...] : { size=15 } [Type: [...]::HashMap<u64, u64, [...]>]
|
// cdb-check:hash_map,d [...] : { len=15 } [Type: [...]::HashMap<u64, u64, [...]>]
|
||||||
// cdb-check: [size] : 15 [Type: [...]]
|
// cdb-check: [len] : 15 [Type: [...]]
|
||||||
// cdb-check: [capacity] : [...]
|
// cdb-check: [capacity] : [...]
|
||||||
// cdb-check: ["0x0"] : 0 [Type: unsigned __int64]
|
// cdb-check: ["0x0"] : 0 [Type: unsigned __int64]
|
||||||
// cdb-command: dx hash_map,d
|
// cdb-command: dx hash_map,d
|
||||||
|
|
|
@ -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
|
// 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-command: dx vec,d
|
||||||
// cdb-check:vec,d [...] : { size=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
|
// cdb-check:vec,d [...] : { len=4 } [Type: [...]::Vec<u64, alloc::alloc::Global>]
|
||||||
// cdb-check: [size] : 4 [Type: [...]]
|
// cdb-check: [len] : 4 [Type: [...]]
|
||||||
// cdb-check: [capacity] : [...] [Type: [...]]
|
// cdb-check: [capacity] : [...] [Type: [...]]
|
||||||
// cdb-check: [0] : 4 [Type: unsigned __int64]
|
// cdb-check: [0] : 4 [Type: unsigned __int64]
|
||||||
// cdb-check: [1] : 5 [Type: unsigned __int64]
|
// cdb-check: [1] : 5 [Type: unsigned __int64]
|
||||||
|
@ -89,8 +89,10 @@
|
||||||
// cdb-command: dx string
|
// cdb-command: dx string
|
||||||
// cdb-check:string : "IAMA string!" [Type: [...]::String]
|
// cdb-check:string : "IAMA string!" [Type: [...]::String]
|
||||||
// cdb-check: [<Raw View>] [Type: [...]::String]
|
// cdb-check: [<Raw View>] [Type: [...]::String]
|
||||||
// cdb-check: [size] : 0xc [Type: [...]]
|
// cdb-check: [len] : 0xc [Type: [...]]
|
||||||
// cdb-check: [capacity] : 0xc [Type: [...]]
|
// cdb-check: [capacity] : 0xc [Type: [...]]
|
||||||
|
|
||||||
|
// cdb-command: dx -r2 string
|
||||||
// cdb-check: [0] : 73 'I' [Type: char]
|
// cdb-check: [0] : 73 'I' [Type: char]
|
||||||
// cdb-check: [1] : 65 'A' [Type: char]
|
// cdb-check: [1] : 65 'A' [Type: char]
|
||||||
// cdb-check: [2] : 77 'M' [Type: char]
|
// cdb-check: [2] : 77 'M' [Type: char]
|
||||||
|
@ -109,11 +111,11 @@
|
||||||
// NOTE: OsString doesn't have a .natvis entry yet.
|
// NOTE: OsString doesn't have a .natvis entry yet.
|
||||||
|
|
||||||
// cdb-command: dx some
|
// 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-command: dx none
|
||||||
// cdb-check:none : { None } [Type: [...]::Option<i64>]
|
// cdb-check:none : None [Type: [...]::Option<i64>]
|
||||||
// cdb-command: dx some_string
|
// 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)]
|
#![allow(unused_variables)]
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
|
7
src/test/rustdoc-ui/reference-links.rs
Normal file
7
src/test/rustdoc-ui/reference-links.rs
Normal 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
|
20
src/test/rustdoc-ui/reference-links.stderr
Normal file
20
src/test/rustdoc-ui/reference-links.stderr
Normal 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
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
|
@ -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`.
|
|
@ -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() {}
|
|
|
@ -1,5 +1,3 @@
|
||||||
// run-rustfix
|
|
||||||
|
|
||||||
#![allow(unused_imports)]
|
#![allow(unused_imports)]
|
||||||
|
|
||||||
pub mod x {
|
pub mod x {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: expected one of `,`, `::`, `as`, or `}`, found `.`
|
error: expected one of `,`, `::`, `as`, or `}`, found `.`
|
||||||
--> $DIR/similar-tokens.rs:11:10
|
--> $DIR/similar-tokens.rs:9:10
|
||||||
|
|
|
|
||||||
LL | use x::{A. B};
|
LL | use x::{A. B};
|
||||||
| ^
|
| ^
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue