2016-06-02 3 views
5

मैं अपने प्रक्रियात्मक मैक्रो को कुछ बाइनरीऑप्स को विधियों के साथ प्रतिस्थापित करना चाहता हूं। मैं स्पैन कैसे सेट करूं ताकि अगर त्रुटियां उत्पन्न हों तो मेरे उपयोगकर्ता पूरी तरह उलझन में नहीं हैं?प्रक्रियात्मक मैक्रोज़ में स्पैन के साथ सही तरीके से कैसे निपटें?

+0

क्या आप एक उदाहरण दे सकते हैं? आप चाहते हैं कि अवधि केवल बाइनरीओपी, या पूरी बाइनरी अभिव्यक्ति को हाइलाइट करे? – kennytm

+0

प्रत्येक एक्सप्रो को एक अवधि की आवश्यकता होती है। हमारे पास मूल 'बाइनरीओपी' एक्सप्र 'है, ऑपरेटर' एक्सप्र '(जो अपरिवर्तित हैं, इसलिए वे अपना' स्पैन 'रखते ​​हैं, नव निर्मित' मेथडकॉल 'एक्सप्रो' दोनों के लिए 'स्पैन' के साथ विधि का 'एक्सप्र' और 'पहचान'। यह उन दो 'स्पैन' है जिन्हें मैं रूचि रखता हूं। – llogiq

उत्तर

1

कुछ rustc के स्रोत को देखने के बाद, मैं निष्कर्ष पर आया कि "विस्तार" मॉडल के बाद सबसे अच्छे परिणाम पैदा होते हैं। इसलिए हम मूल Span रखते हैं लेकिन expn_id के लिए, जिसे हम ExtCtxt::backtrace() पर कॉल करके प्राप्त कर सकते हैं।

प्रश्न में उल्लिखित दोनों मामलों में इसे स्थापित करना एक अच्छा विचार प्रतीत होता है। ऑपरेटर को फ़ंक्शन कॉल में विस्तारित (फ़ंक्शन कॉल) पथ में विस्तारित किया जा सकता है, और मूल बाइनरी ऑपरेशन अभिव्यक्ति के रूप में देखा जा सकता है। कोड में:

match expr.unwrap() { 
    .. 
    Expr { node: ExprKind::Binary(Spanned { node: Add, span: op }, l, r), span, .. } => { 
     let bt = self.cx.backtrace(); // get the expansion ID 
     let path = self.cx.path(Span { expn_id: bt, ..op }, vec![crate_name, trait_name, fn_name]); 
     let epath = self.cx.expr_path(path); // path expression 
     let args_expanded = self.fold_exprs(args); 
     self.cx.expr_call(Span { expn_id: bt, ..span }, epath, args_expanded) 
     //^outer expression 
    } 
    .. 
} 
संबंधित मुद्दे